From a9b858ec6f4e32098e4f494cf85ed3a8b0adf927 Mon Sep 17 00:00:00 2001 From: FlyLoongZ <60963681+FlyLoongZ@users.noreply.github.com> Date: Mon, 11 Aug 2025 16:28:23 +0800 Subject: [PATCH] feat: Add AI API Custom Header --- src/apis/trans.js | 15 +++++++++++++++ src/config/i18n.js | 10 +++++++++- src/config/index.js | 5 +++++ src/views/Options/Apis.js | 15 +++++++++++++-- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/apis/trans.js b/src/apis/trans.js index ba5b4f8..575dc3e 100644 --- a/src/apis/trans.js +++ b/src/apis/trans.js @@ -240,6 +240,7 @@ const genOpenAI = ({ model, temperature, maxTokens, + customHeader, customBody, }) => { // 兼容历史上作为systemPrompt的prompt,如果prompt中不包含带翻译文本,则添加文本到prompt末尾 @@ -255,6 +256,7 @@ const genOpenAI = ({ .replaceAll(INPUT_PLACE_TO, to) .replaceAll(INPUT_PLACE_TEXT, text); + customHeader = JSON.parse("{" + customHeader + "}"); customBody = JSON.parse("{" + customBody + "}"); const data = { @@ -279,6 +281,7 @@ const genOpenAI = ({ "Content-type": "application/json", Authorization: `Bearer ${key}`, // OpenAI "api-key": key, // Azure OpenAI + ...customHeader, }, method: "POST", body: JSON.stringify(data), @@ -298,6 +301,7 @@ const genGemini = ({ model, temperature, maxTokens, + customHeader, customBody, }) => { url = url @@ -312,6 +316,7 @@ const genGemini = ({ .replaceAll(INPUT_PLACE_TO, to) .replaceAll(INPUT_PLACE_TEXT, text); + customHeader = JSON.parse("{" + customHeader + "}"); customBody = JSON.parse("{" + customBody + "}"); const data = { @@ -338,6 +343,7 @@ const genGemini = ({ const init = { headers: { "Content-type": "application/json", + ...customHeader, }, method: "POST", body: JSON.stringify(data), @@ -357,6 +363,7 @@ const genGemini2 = ({ model, temperature, maxTokens, + customHeader, customBody, }) => { systemPrompt = systemPrompt @@ -368,6 +375,7 @@ const genGemini2 = ({ .replaceAll(INPUT_PLACE_TO, to) .replaceAll(INPUT_PLACE_TEXT, text); + customHeader = JSON.parse("{" + customHeader + "}"); customBody = JSON.parse("{" + customBody + "}"); const data = { @@ -391,6 +399,7 @@ const genGemini2 = ({ headers: { "Content-type": "application/json", Authorization: `Bearer ${key}`, + ...customHeader, }, method: "POST", body: JSON.stringify(data), @@ -410,6 +419,7 @@ const genClaude = ({ model, temperature, maxTokens, + customHeader, customBody, }) => { systemPrompt = systemPrompt @@ -421,6 +431,7 @@ const genClaude = ({ .replaceAll(INPUT_PLACE_TO, to) .replaceAll(INPUT_PLACE_TEXT, text); + customHeader = JSON.parse("{" + customHeader + "}"); customBody = JSON.parse("{" + customBody + "}"); const data = { @@ -442,6 +453,7 @@ const genClaude = ({ "Content-type": "application/json", "anthropic-version": "2023-06-01", "x-api-key": key, + ...customHeader, }, method: "POST", body: JSON.stringify(data), @@ -460,6 +472,7 @@ const genOllama = ({ systemPrompt, userPrompt, model, + customHeader, customBody, }) => { systemPrompt = systemPrompt @@ -471,6 +484,7 @@ const genOllama = ({ .replaceAll(INPUT_PLACE_TO, to) .replaceAll(INPUT_PLACE_TEXT, text); + customHeader = JSON.parse("{" + customHeader + "}"); customBody = JSON.parse("{" + customBody + "}"); const data = { @@ -485,6 +499,7 @@ const genOllama = ({ const init = { headers: { "Content-type": "application/json", + ...customHeader, }, method: "POST", body: JSON.stringify(data), diff --git a/src/config/i18n.js b/src/config/i18n.js index fb05652..805e37d 100644 --- a/src/config/i18n.js +++ b/src/config/i18n.js @@ -228,9 +228,17 @@ export const I18N = { zh: `请求超时时间 (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: { zh: `自定义Body参数`, - en: `API Custom Params`, + en: `Custom Body Params`, }, custom_body_help: { zh: `使用JSON格式,例如 "top_p": 0.7`, diff --git a/src/config/index.js b/src/config/index.js index 184535c..0427070 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -563,6 +563,7 @@ const defaultOpenaiApi = { model: "gpt-4", 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:`, + customHeader: "", customBody: "", temperature: 0, maxTokens: 256, @@ -578,6 +579,7 @@ const defaultOllamaApi = { model: "llama3.1", 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:`, + customHeader: "", customBody: "", think: false, thinkIgnore: `qwen3,deepseek-r1`, @@ -679,6 +681,7 @@ export const DEFAULT_TRANS_APIS = { model: "gemini-2.5-flash", 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:`, + customHeader: "", customBody: "", temperature: 0, maxTokens: 2048, @@ -694,6 +697,7 @@ export const DEFAULT_TRANS_APIS = { model: "gemini-2.0-flash", 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:`, + customHeader: "", customBody: "", temperature: 0, maxTokens: 2048, @@ -709,6 +713,7 @@ export const DEFAULT_TRANS_APIS = { model: "claude-3-haiku-20240307", 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:`, + customHeader: "", customBody: "", temperature: 0, maxTokens: 1024, diff --git a/src/views/Options/Apis.js b/src/views/Options/Apis.js index f64ebaf..fe7bacf 100644 --- a/src/views/Options/Apis.js +++ b/src/views/Options/Apis.js @@ -125,6 +125,7 @@ function ApiFields({ translator, api, updateApi, resetApi }) { model = "", systemPrompt = "", userPrompt = "", + customHeader = "", customBody = "", think = false, thinkIgnore = "", @@ -277,13 +278,23 @@ function ApiFields({ translator, api, updateApi, resetApi }) { /> + )}