feat: Add AI API Custom Header
This commit is contained in:
@@ -240,6 +240,7 @@ const genOpenAI = ({
|
|||||||
model,
|
model,
|
||||||
temperature,
|
temperature,
|
||||||
maxTokens,
|
maxTokens,
|
||||||
|
customHeader,
|
||||||
customBody,
|
customBody,
|
||||||
}) => {
|
}) => {
|
||||||
// 兼容历史上作为systemPrompt的prompt,如果prompt中不包含带翻译文本,则添加文本到prompt末尾
|
// 兼容历史上作为systemPrompt的prompt,如果prompt中不包含带翻译文本,则添加文本到prompt末尾
|
||||||
@@ -255,6 +256,7 @@ const genOpenAI = ({
|
|||||||
.replaceAll(INPUT_PLACE_TO, to)
|
.replaceAll(INPUT_PLACE_TO, to)
|
||||||
.replaceAll(INPUT_PLACE_TEXT, text);
|
.replaceAll(INPUT_PLACE_TEXT, text);
|
||||||
|
|
||||||
|
customHeader = JSON.parse("{" + customHeader + "}");
|
||||||
customBody = JSON.parse("{" + customBody + "}");
|
customBody = JSON.parse("{" + customBody + "}");
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@@ -279,6 +281,7 @@ const genOpenAI = ({
|
|||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
Authorization: `Bearer ${key}`, // OpenAI
|
Authorization: `Bearer ${key}`, // OpenAI
|
||||||
"api-key": key, // Azure OpenAI
|
"api-key": key, // Azure OpenAI
|
||||||
|
...customHeader,
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
@@ -298,6 +301,7 @@ const genGemini = ({
|
|||||||
model,
|
model,
|
||||||
temperature,
|
temperature,
|
||||||
maxTokens,
|
maxTokens,
|
||||||
|
customHeader,
|
||||||
customBody,
|
customBody,
|
||||||
}) => {
|
}) => {
|
||||||
url = url
|
url = url
|
||||||
@@ -312,6 +316,7 @@ const genGemini = ({
|
|||||||
.replaceAll(INPUT_PLACE_TO, to)
|
.replaceAll(INPUT_PLACE_TO, to)
|
||||||
.replaceAll(INPUT_PLACE_TEXT, text);
|
.replaceAll(INPUT_PLACE_TEXT, text);
|
||||||
|
|
||||||
|
customHeader = JSON.parse("{" + customHeader + "}");
|
||||||
customBody = JSON.parse("{" + customBody + "}");
|
customBody = JSON.parse("{" + customBody + "}");
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@@ -338,6 +343,7 @@ const genGemini = ({
|
|||||||
const init = {
|
const init = {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
|
...customHeader,
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
@@ -357,6 +363,7 @@ const genGemini2 = ({
|
|||||||
model,
|
model,
|
||||||
temperature,
|
temperature,
|
||||||
maxTokens,
|
maxTokens,
|
||||||
|
customHeader,
|
||||||
customBody,
|
customBody,
|
||||||
}) => {
|
}) => {
|
||||||
systemPrompt = systemPrompt
|
systemPrompt = systemPrompt
|
||||||
@@ -368,6 +375,7 @@ const genGemini2 = ({
|
|||||||
.replaceAll(INPUT_PLACE_TO, to)
|
.replaceAll(INPUT_PLACE_TO, to)
|
||||||
.replaceAll(INPUT_PLACE_TEXT, text);
|
.replaceAll(INPUT_PLACE_TEXT, text);
|
||||||
|
|
||||||
|
customHeader = JSON.parse("{" + customHeader + "}");
|
||||||
customBody = JSON.parse("{" + customBody + "}");
|
customBody = JSON.parse("{" + customBody + "}");
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@@ -391,6 +399,7 @@ const genGemini2 = ({
|
|||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
Authorization: `Bearer ${key}`,
|
Authorization: `Bearer ${key}`,
|
||||||
|
...customHeader,
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
@@ -410,6 +419,7 @@ const genClaude = ({
|
|||||||
model,
|
model,
|
||||||
temperature,
|
temperature,
|
||||||
maxTokens,
|
maxTokens,
|
||||||
|
customHeader,
|
||||||
customBody,
|
customBody,
|
||||||
}) => {
|
}) => {
|
||||||
systemPrompt = systemPrompt
|
systemPrompt = systemPrompt
|
||||||
@@ -421,6 +431,7 @@ const genClaude = ({
|
|||||||
.replaceAll(INPUT_PLACE_TO, to)
|
.replaceAll(INPUT_PLACE_TO, to)
|
||||||
.replaceAll(INPUT_PLACE_TEXT, text);
|
.replaceAll(INPUT_PLACE_TEXT, text);
|
||||||
|
|
||||||
|
customHeader = JSON.parse("{" + customHeader + "}");
|
||||||
customBody = JSON.parse("{" + customBody + "}");
|
customBody = JSON.parse("{" + customBody + "}");
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@@ -442,6 +453,7 @@ const genClaude = ({
|
|||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
"anthropic-version": "2023-06-01",
|
"anthropic-version": "2023-06-01",
|
||||||
"x-api-key": key,
|
"x-api-key": key,
|
||||||
|
...customHeader,
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
@@ -460,6 +472,7 @@ const genOllama = ({
|
|||||||
systemPrompt,
|
systemPrompt,
|
||||||
userPrompt,
|
userPrompt,
|
||||||
model,
|
model,
|
||||||
|
customHeader,
|
||||||
customBody,
|
customBody,
|
||||||
}) => {
|
}) => {
|
||||||
systemPrompt = systemPrompt
|
systemPrompt = systemPrompt
|
||||||
@@ -471,6 +484,7 @@ const genOllama = ({
|
|||||||
.replaceAll(INPUT_PLACE_TO, to)
|
.replaceAll(INPUT_PLACE_TO, to)
|
||||||
.replaceAll(INPUT_PLACE_TEXT, text);
|
.replaceAll(INPUT_PLACE_TEXT, text);
|
||||||
|
|
||||||
|
customHeader = JSON.parse("{" + customHeader + "}");
|
||||||
customBody = JSON.parse("{" + customBody + "}");
|
customBody = JSON.parse("{" + customBody + "}");
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@@ -485,6 +499,7 @@ const genOllama = ({
|
|||||||
const init = {
|
const init = {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
|
...customHeader,
|
||||||
},
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
|
|||||||
@@ -228,9 +228,17 @@ export const I18N = {
|
|||||||
zh: `请求超时时间 (5000-30000ms)`,
|
zh: `请求超时时间 (5000-30000ms)`,
|
||||||
en: `Request Timeout Time (5000-30000ms)`,
|
en: `Request Timeout Time (5000-30000ms)`,
|
||||||
},
|
},
|
||||||
|
custom_header: {
|
||||||
|
zh: `自定义Header参数`,
|
||||||
|
en: `Custom Header Params`,
|
||||||
|
},
|
||||||
|
custom_header_help: {
|
||||||
|
zh: `使用JSON格式,例如 "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:141.0) Gecko/20100101 Firefox/141.0"`,
|
||||||
|
en: `Use JSON format, for example "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:141.0) Gecko/20100101 Firefox/141.0"`,
|
||||||
|
},
|
||||||
custom_body: {
|
custom_body: {
|
||||||
zh: `自定义Body参数`,
|
zh: `自定义Body参数`,
|
||||||
en: `API Custom Params`,
|
en: `Custom Body Params`,
|
||||||
},
|
},
|
||||||
custom_body_help: {
|
custom_body_help: {
|
||||||
zh: `使用JSON格式,例如 "top_p": 0.7`,
|
zh: `使用JSON格式,例如 "top_p": 0.7`,
|
||||||
|
|||||||
@@ -563,6 +563,7 @@ const defaultOpenaiApi = {
|
|||||||
model: "gpt-4",
|
model: "gpt-4",
|
||||||
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
||||||
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
||||||
|
customHeader: "",
|
||||||
customBody: "",
|
customBody: "",
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
maxTokens: 256,
|
maxTokens: 256,
|
||||||
@@ -578,6 +579,7 @@ const defaultOllamaApi = {
|
|||||||
model: "llama3.1",
|
model: "llama3.1",
|
||||||
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
||||||
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
||||||
|
customHeader: "",
|
||||||
customBody: "",
|
customBody: "",
|
||||||
think: false,
|
think: false,
|
||||||
thinkIgnore: `qwen3,deepseek-r1`,
|
thinkIgnore: `qwen3,deepseek-r1`,
|
||||||
@@ -679,6 +681,7 @@ export const DEFAULT_TRANS_APIS = {
|
|||||||
model: "gemini-2.5-flash",
|
model: "gemini-2.5-flash",
|
||||||
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
||||||
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
||||||
|
customHeader: "",
|
||||||
customBody: "",
|
customBody: "",
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
maxTokens: 2048,
|
maxTokens: 2048,
|
||||||
@@ -694,6 +697,7 @@ export const DEFAULT_TRANS_APIS = {
|
|||||||
model: "gemini-2.0-flash",
|
model: "gemini-2.0-flash",
|
||||||
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
||||||
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
||||||
|
customHeader: "",
|
||||||
customBody: "",
|
customBody: "",
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
maxTokens: 2048,
|
maxTokens: 2048,
|
||||||
@@ -709,6 +713,7 @@ export const DEFAULT_TRANS_APIS = {
|
|||||||
model: "claude-3-haiku-20240307",
|
model: "claude-3-haiku-20240307",
|
||||||
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
systemPrompt: `You are a professional, authentic machine translation engine.`,
|
||||||
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
userPrompt: `Translate the following source text from ${INPUT_PLACE_FROM} to ${INPUT_PLACE_TO}. Output translation directly without any additional text.\n\nSource Text: ${INPUT_PLACE_TEXT}\n\nTranslated Text:`,
|
||||||
|
customHeader: "",
|
||||||
customBody: "",
|
customBody: "",
|
||||||
temperature: 0,
|
temperature: 0,
|
||||||
maxTokens: 1024,
|
maxTokens: 1024,
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ function ApiFields({ translator, api, updateApi, resetApi }) {
|
|||||||
model = "",
|
model = "",
|
||||||
systemPrompt = "",
|
systemPrompt = "",
|
||||||
userPrompt = "",
|
userPrompt = "",
|
||||||
|
customHeader = "",
|
||||||
customBody = "",
|
customBody = "",
|
||||||
think = false,
|
think = false,
|
||||||
thinkIgnore = "",
|
thinkIgnore = "",
|
||||||
@@ -277,13 +278,23 @@ function ApiFields({ translator, api, updateApi, resetApi }) {
|
|||||||
/>
|
/>
|
||||||
<TextField
|
<TextField
|
||||||
size="small"
|
size="small"
|
||||||
label={i18n("api_custom_params")}
|
label={i18n("custom_header")}
|
||||||
|
name="customHeader"
|
||||||
|
value={customHeader}
|
||||||
|
onChange={handleChange}
|
||||||
|
multiline
|
||||||
|
maxRows={10}
|
||||||
|
helperText={i18n("custom_header_help")}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
size="small"
|
||||||
|
label={i18n("custom_body")}
|
||||||
name="customBody"
|
name="customBody"
|
||||||
value={customBody}
|
value={customBody}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
multiline
|
multiline
|
||||||
maxRows={10}
|
maxRows={10}
|
||||||
helperText={i18n("api_custom_params_help")}
|
helperText={i18n("custom_body_help")}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user