Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 添加Azure OpenAI Service支持 #93

Merged
merged 1 commit into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 33 additions & 14 deletions src/interfaces/openai.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@ export const info = {
needs: [
{
config_key: 'openai_domain',
place_hold: 'api.openai.com',
place_hold: 'api.openai.com(不要加协议头,使用OpenAI官方api此项留空即可)',
display_name: '自定义域名',
},
{
config_key: 'openai_path',
place_hold: '/v1/chat/completions(一般不需要改,留空即可,Azure用户根据自己情况修改)',
display_name: '请求路径',
},
{
config_key: 'openai_apikey',
place_hold: '',
Expand All @@ -41,26 +46,35 @@ export async function translate(text, from, to, setText) {
if (domain == '') {
domain = 'api.openai.com';
}
if (domain.startsWith('http')) {
domain = domain.replace('https://', '').replace('http://', '');
}
let path = get('openai_path') ?? '/v1/chat/completions';
if (path == '') {
path = '/v1/chat/completions';
}
const apikey = get('openai_apikey') ?? '';
if (apikey == '') {
throw '请先配置apikey';
}
let prompt = get('openai_prompt') ?? '';
if (prompt == '') {
prompt =
'You are a professional translation engine, please translate the text into a colloquial, professional, elegant and fluent content, without the style of machine translation. You must only translate the text content, never interpret it.';
let systemPrompt = get('openai_prompt') ?? '';
if (systemPrompt == '') {
systemPrompt = 'You are a professional translation engine, please translate the text into a colloquial, professional, elegant and fluent content, without the style of machine translation. You must only translate the text content, never interpret it.';
}
let userPrompt = `If the content is in ${supportLanguage[to]}, then translate into ${supportLanguage[get('second_language') ?? 'en']}. Otherwise, translate into ${supportLanguage[to]}:\n"""\n${text}\n"""`;

const stream = get('openai_stream') ?? false;
const service = get('openai_service') ?? 'openai';

const headers = {
const headers = service == 'openai' ? {
'Content-Type': 'application/json',
Authorization: `Bearer ${apikey}`,
};
let systemPrompt = prompt;

let userPrompt = `If the content is in ${supportLanguage[to]}, then translate into ${supportLanguage[get('second_language') ?? 'en']}. Otherwise, translate into ${supportLanguage[to]}:\n"""\n${text}\n"""`;
} : {
'Content-Type': 'application/json',
Authorization: `api-key: ${apikey}`,
}

const body = {
const body = service == 'openai' ? {
model: 'gpt-3.5-turbo',
temperature: 0,
max_tokens: 1000,
Expand All @@ -72,10 +86,15 @@ export async function translate(text, from, to, setText) {
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
],
};
} : {
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
]
}

if (stream) {
const res = await window.fetch(`https://${domain}/v1/chat/completions`, {
const res = await window.fetch(`https://${domain}${path}`, {
method: 'POST',
headers: headers,
body: JSON.stringify(body)
Expand Down Expand Up @@ -123,7 +142,7 @@ export async function translate(text, from, to, setText) {
throw 'http请求出错\n' + JSON.stringify(res);
}
} else {
let res = await fetch(`https://${domain}/v1/chat/completions`, {
let res = await fetch(`https://${domain}${path}`, {
method: 'POST',
headers: headers,
body: { type: 'Json', payload: body },
Expand Down
36 changes: 26 additions & 10 deletions src/interfaces/openai_code.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,36 @@ export async function translate(text, from, to, setText) {
if (domain == '') {
domain = 'api.openai.com';
}
if (domain.startsWith('http')) {
domain = domain.replace('https://', '').replace('http://', '');
}
let path = get('openai_path') ?? '/v1/chat/completions';
if (path == '') {
path = '/v1/chat/completions';
}
const apikey = get('openai_apikey') ?? '';
if (apikey == '') {
throw '请先配置apikey';
}
let prompt = get('openai_code_prompt') ?? '';
if (prompt == '') {
prompt =
let systemPrompt = get('openai_code_prompt') ?? '';
if (systemPrompt == '') {
systemPrompt =
'You are a code explanation engine, you can only explain the code, do not interpret or translate it. Also, please report any bugs you find in the code to the author of the code.';
}
let userPrompt = `Explain the following code in ${supportLanguage[to]}:\n"""\n${text}\n"""`;

const stream = get('openai_stream') ?? false;
const headers = {
const service = get('openai_service') ?? 'openai';

const headers = service == 'openai' ? {
'Content-Type': 'application/json',
Authorization: `Bearer ${apikey}`,
};

let systemPrompt = prompt;
let userPrompt = `Explain the following code in ${supportLanguage[to]}:\n"""\n${text}\n"""`;
} : {
'Content-Type': 'application/json',
Authorization: `api-key: ${apikey}`,
}

const body = {
const body = service == 'openai' ? {
model: 'gpt-3.5-turbo',
temperature: 0,
max_tokens: 1000,
Expand All @@ -61,7 +72,12 @@ export async function translate(text, from, to, setText) {
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
],
};
} : {
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
]
}

if (stream) {
const res = await window.fetch(`https://${domain}/v1/chat/completions`, {
Expand Down
35 changes: 25 additions & 10 deletions src/interfaces/openai_polish.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,34 @@ export async function translate(text, from, to, setText) {
if (domain == '') {
domain = 'api.openai.com';
}
if (domain.startsWith('http')) {
domain = domain.replace('https://', '').replace('http://', '');
}
let path = get('openai_path') ?? '/v1/chat/completions';
if (path == '') {
path = '/v1/chat/completions';
}
const apikey = get('openai_apikey') ?? '';
if (apikey == '') {
throw '请先配置apikey';
}
let prompt = get('openai_polish_prompt') ?? '';
if (prompt == '') {
prompt = "You are a text embellisher, you can only embellish the text, don't interpret it.";
let systemPrompt = get('openai_polish_prompt') ?? '';
if (systemPrompt == '') {
systemPrompt = "You are a text embellisher, you can only embellish the text, don't interpret it.";
}
let userPrompt = `Embellish in ${supportLanguage[to]}:\n"""\n${text}\n"""`;
const stream = get('openai_stream') ?? false;
const headers = {
const service = get('openai_service') ?? 'openai';

const headers = service == 'openai' ? {
'Content-Type': 'application/json',
Authorization: `Bearer ${apikey}`,
};

let systemPrompt = prompt;
let userPrompt = `Embellish in ${supportLanguage[to]}:\n"""\n${text}\n"""`;
} : {
'Content-Type': 'application/json',
Authorization: `api-key: ${apikey}`,
}

const body = {
const body = service == 'openai' ? {
model: 'gpt-3.5-turbo',
temperature: 0,
max_tokens: 1000,
Expand All @@ -59,7 +69,12 @@ export async function translate(text, from, to, setText) {
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
],
};
} : {
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
]
}

if (stream) {
const res = await window.fetch(`https://${domain}/v1/chat/completions`, {
Expand Down
35 changes: 25 additions & 10 deletions src/interfaces/openai_summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,34 @@ export async function translate(text, from, to, setText) {
if (domain == '') {
domain = 'api.openai.com';
}
if (domain.startsWith('http')) {
domain = domain.replace('https://', '').replace('http://', '');
}
let path = get('openai_path') ?? '/v1/chat/completions';
if (path == '') {
path = '/v1/chat/completions';
}
const apikey = get('openai_apikey') ?? '';
if (apikey == '') {
throw '请先配置apikey';
}
let prompt = get('openai_summary_prompt') ?? '';
if (prompt == '') {
prompt = "You are a text summarizer, you can only summarize the text, don't interpret it.";
let systemPrompt = get('openai_summary_prompt') ?? '';
if (systemPrompt == '') {
systemPrompt = "You are a text summarizer, you can only summarize the text, don't interpret it.";
}
let userPrompt = `Summarize in ${supportLanguage[to]}:\n"""\n${text}\n"""`;
const stream = get('openai_stream') ?? false;
const headers = {
const service = get('openai_service') ?? 'openai';

const headers = service == 'openai' ? {
'Content-Type': 'application/json',
Authorization: `Bearer ${apikey}`,
};

let systemPrompt = prompt;
let userPrompt = `Summarize in ${supportLanguage[to]}:\n"""\n${text}\n"""`;
} : {
'Content-Type': 'application/json',
Authorization: `api-key: ${apikey}`,
}

const body = {
const body = service == 'openai' ? {
model: 'gpt-3.5-turbo',
temperature: 0,
max_tokens: 1000,
Expand All @@ -59,7 +69,12 @@ export async function translate(text, from, to, setText) {
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
],
};
} : {
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt },
]
}

if (stream) {
const res = await window.fetch(`https://${domain}/v1/chat/completions`, {
Expand Down
3 changes: 3 additions & 0 deletions src/windows/Config/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const ankiEnableAtom = atom(true);
export const eudicEnableAtom = atom(true);
export const eudicCategoryNameAtom = atom('');
export const eudicTokenAtom = atom('');
export const openaiServiceAtom = atom('openai');
export const interfaceConfigsAtom = atom({});
export const shortcutTranslateAtom = atom('');
export const shortcutPersistentAtom = atom('');
Expand All @@ -41,6 +42,7 @@ export default function Config() {
const setShortcutTranslate = useSetAtom(shortcutTranslateAtom);
const setShortcutPersistent = useSetAtom(shortcutPersistentAtom);
const setShortcutOcr = useSetAtom(shortcutOcrAtom);
const setOpenaiService = useSetAtom(openaiServiceAtom);
const setInterfaceConfigs = useSetAtom(interfaceConfigsAtom);
const setAutoStart = useSetAtom(autoStartAtom);
const setAutoCheck = useSetAtom(autoCheckAtom);
Expand Down Expand Up @@ -95,6 +97,7 @@ export default function Config() {
setEudicCategoryName(get('eudic_category_name') ?? 'pot');
setEudicToken(get('eudic_token') ?? '');
setTheme(get('theme') ?? 'auto');
setOpenaiService(get('openai_service') ?? 'openai');
let interface_configs = {};

Object.keys(interfaces).map((i) => {
Expand Down
20 changes: 18 additions & 2 deletions src/windows/Config/pages/InterfaceConfig/index.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
import { TextField, Switch, FormControlLabel } from '@mui/material';
import { TextField, Switch, FormControlLabel, Select, MenuItem, Tooltip } from '@mui/material';
import { useAtom } from 'jotai';
import { nanoid } from 'nanoid';
import React from 'react';
import { interfaceConfigsAtom, openaiServiceAtom } from '../..';
import ConfigList from '../../components/ConfigList';
import ConfigItem from '../../components/ConfigItem';
import { set } from '../../../../global/config';
import { interfaceConfigsAtom } from '../..';

export default function InterfaceConfig() {
const [interfaceConfigs, setInterfaceConfigs] = useAtom(interfaceConfigsAtom);
const [openaiService, setOpenaiService] = useAtom(openaiServiceAtom);

return (
<ConfigList label='翻译接口'>
<ConfigItem label='OpenAI 服务提供商'>
<Tooltip title='仅在你明确清楚自己使用的是Azure的OpenAI Service的时候需要设置此项,其他情况下一律使用默认openai服务'>
<Select
fullWidth
value={openaiService}
onChange={(e) => {
setOpenaiService(e.target.value);
set('openai_service', e.target.value);
}}
>
<MenuItem value='openai'>OpenAI</MenuItem>
<MenuItem value='azure'>Azure</MenuItem>
</Select>
</Tooltip>
</ConfigItem>
{Object.keys(interfaceConfigs).map((x) => {
return (
<ConfigItem
Expand Down