From 10160ee694b519b76085d95c052413f4dcfb71f9 Mon Sep 17 00:00:00 2001 From: Steven_Zhu Date: Sat, 20 Jun 2026 17:12:30 +0100 Subject: [PATCH 1/2] feat: migrate DeepSeek integration to V4 models --- docs/config/translation-engines.md | 2 +- entrypoints/service/deepseek.ts | 16 ++++++++++-- entrypoints/utils/check.ts | 8 +++--- entrypoints/utils/option.ts | 2 +- entrypoints/utils/template.ts | 41 +++++++++++++++++++++++++----- 5 files changed, 53 insertions(+), 16 deletions(-) diff --git a/docs/config/translation-engines.md b/docs/config/translation-engines.md index c3f238b..dadd62f 100644 --- a/docs/config/translation-engines.md +++ b/docs/config/translation-engines.md @@ -48,7 +48,7 @@ 2. 点击设置图标,进入设置页面 3. 选择 "翻译引擎" 选项卡 4. 在引擎列表中选择 "DeepSeek" -5. 选择 `deepseek-chat` 模型,并填入配置信息 +5. 选择 `deepseek-v4-flash` 模型,并填入配置信息 点击流畅阅读图标 diff --git a/entrypoints/service/deepseek.ts b/entrypoints/service/deepseek.ts index c7c30f2..a1fb3a9 100644 --- a/entrypoints/service/deepseek.ts +++ b/entrypoints/service/deepseek.ts @@ -23,11 +23,23 @@ async function deepseek(message: any) { } const result = await resp.json(); - return contentPostHandler(result.choices[0].message.content); + return extractDeepSeekContent(result); } catch (error) { console.error('API调用失败:', error); throw error; } } -export default deepseek; \ No newline at end of file +function extractDeepSeekContent(result: any): string { + const content = result?.choices?.[0]?.message?.content; + + if (typeof content !== 'string') { + throw new Error('DeepSeek 返回数据格式异常:缺少 choices[0].message.content'); + } + + // Only final message.content is rendered. DeepSeek thinking fields such as + // reasoning_content are intentionally ignored and must never reach the page. + return contentPostHandler(content); +} + +export default deepseek; diff --git a/entrypoints/utils/check.ts b/entrypoints/utils/check.ts index 955bd3a..8b2cece 100644 --- a/entrypoints/utils/check.ts +++ b/entrypoints/utils/check.ts @@ -98,8 +98,6 @@ export function searchClassName(node: Node, className: string): Node | null { } export function contentPostHandler(text: string) { - // 替换掉之间的内容 - let content = text; - content = content.replace(/^[\s\S]*?<\/think>/, ""); - return content; -} \ No newline at end of file + // Never render model reasoning tags in translated page content. + return text.replace(/[\s\S]*?<\/think>/gi, "").trim(); +} diff --git a/entrypoints/utils/option.ts b/entrypoints/utils/option.ts index 8293314..4c70270 100644 --- a/entrypoints/utils/option.ts +++ b/entrypoints/utils/option.ts @@ -186,7 +186,7 @@ export const models = new Map>([ [services.infini, ["llama-2-13b-chat", "llama-3.3-70b-instruct", "qwen2.5-14b-instruct", "gemma-2-27b-it", "glm-4-9b-chat", customModelString]], [services.baichuan, ["Baichuan4-Air", "Baichuan4-Turbo", "Baichuan4", customModelString]], [services.lingyi, ["yi-lightning", customModelString]], - [services.deepseek, ["deepseek-chat", "deepseek-reasoner", customModelString]], + [services.deepseek, ["deepseek-v4-flash", "deepseek-v4-pro", customModelString]], [services.minimax, ["chatcompletion_v2"]], [services.jieyue, ["step-1-8k", customModelString]], [services.huanYuan, ["hunyuan-turbos-latest", "hunyuan-t1-latest", "hunyuan-a13b", "hunyuan-lite", "hunyuan-standard", customModelString]], diff --git a/entrypoints/utils/template.ts b/entrypoints/utils/template.ts index 865b492..38f7b32 100644 --- a/entrypoints/utils/template.ts +++ b/entrypoints/utils/template.ts @@ -2,6 +2,13 @@ import {customModelString, defaultOption, services} from "./option"; import {config} from "@/entrypoints/utils/config"; +type DeepSeekThinkingMode = 'enabled' | 'disabled'; + +interface DeepSeekModelConfig { + model: string; + thinking: DeepSeekThinkingMode; +} + // openai 格式的消息模板(通用模板) export function commonMsgTemplate(origin: string) { // 检测是否使用自定义模型 @@ -27,31 +34,51 @@ export function commonMsgTemplate(origin: string) { // deepseek export function deepseekMsgTemplate(origin: string) { // 检测是否使用自定义模型 - let model = config.model[config.service] === customModelString ? config.customModel[config.service] : config.model[config.service] + const selectedModel = config.model[config.service] === customModelString ? config.customModel[config.service] : config.model[config.service] - // 删除模型名称中的中文括号及其内容,如"gpt-4(推荐)" -> "gpt-4" - model = model.replace(/(.*)/g, ""); + const modelConfig = normalizeDeepSeekModel(selectedModel); let system = config.system_role[config.service] || defaultOption.system_role; let user = (config.user_role[config.service] || defaultOption.user_role) .replace('{{to}}', config.to).replace('{{origin}}', origin); const payload: any = { - 'model': model, + 'model': modelConfig.model, 'messages': [ {'role': 'system', 'content': system}, {'role': 'user', 'content': user}, - ] + ], + // DeepSeek OpenAI-format Chat Completion / Thinking Mode docs, checked 2026-06-20: + // direct REST requests use top-level {"thinking": {"type": "enabled" | "disabled"}}. + 'thinking': {'type': modelConfig.thinking} }; - // 如果不是 deepseek-reasoner 模型,则添加 temperature - if (model !== 'deepseek-reasoner') { + if (modelConfig.thinking === 'enabled') { + payload.reasoning_effort = 'high'; + } else { payload.temperature = 0.7; } return JSON.stringify(payload); } +function normalizeDeepSeekModel(model: string): DeepSeekModelConfig { + const normalizedModel = (model || '').replace(/(.*)/g, ""); + + // Legacy DeepSeek names are scheduled for deprecation on 2026-07-24. + // Keep saved configs working while preserving their semantics: + // deepseek-chat stays non-thinking; deepseek-reasoner stays thinking-capable. + if (normalizedModel === 'deepseek-chat') { + return {model: 'deepseek-v4-flash', thinking: 'disabled'}; + } + + if (normalizedModel === 'deepseek-reasoner') { + return {model: 'deepseek-v4-pro', thinking: 'enabled'}; + } + + return {model: normalizedModel, thinking: 'disabled'}; +} + // gemini export function geminiMsgTemplate(origin: string) { let user = (config.user_role[config.service] || defaultOption.user_role) From 7c1e5d10bf82dd3b7c25960aba4d097e67c5ebfb Mon Sep 17 00:00:00 2001 From: Steven_Zhu Date: Sat, 20 Jun 2026 17:13:15 +0100 Subject: [PATCH 2/2] chore: fix TypeScript compile issues --- package.json | 3 +- pnpm-lock.yaml | 116 +++++++++---------------------------------------- 2 files changed, 23 insertions(+), 96 deletions(-) diff --git a/package.json b/package.json index e8b17fb..3b3d2c4 100644 --- a/package.json +++ b/package.json @@ -28,13 +28,14 @@ "webextension-polyfill": "^0.12.0" }, "devDependencies": { + "@types/chrome": "^0.2.0", "@types/crypto-js": "^4.2.2", "@types/webextension-polyfill": "^0.12.1", "@vitejs/plugin-vue": "^5.2.1", "@vuepress/client": "2.0.0-rc.19", "@wxt-dev/webextension-polyfill": "^1.0.0", "typescript": "^5.7.3", - "vite": "^5.4.11", + "vite": "^5.4.19", "vite-plugin-imagemin": "^0.6.1", "vitepress": "^1.6.3", "vue": "^3.5.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 54b3497..680e437 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,9 @@ importers: specifier: ^0.12.0 version: 0.12.0 devDependencies: + '@types/chrome': + specifier: ^0.2.0 + version: 0.2.0 '@types/crypto-js': specifier: ^4.2.2 version: 4.2.2 @@ -41,7 +44,7 @@ importers: version: 0.12.1 '@vitejs/plugin-vue': specifier: ^5.2.1 - version: 5.2.1(vite@5.4.11(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3)) + version: 5.2.1(vite@5.4.19(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3)) '@vuepress/client': specifier: 2.0.0-rc.19 version: 2.0.0-rc.19(typescript@5.7.3) @@ -52,11 +55,11 @@ importers: specifier: ^5.7.3 version: 5.7.3 vite: - specifier: ^5.4.11 - version: 5.4.11(@types/node@22.10.7) + specifier: ^5.4.19 + version: 5.4.19(@types/node@22.10.7) vite-plugin-imagemin: specifier: ^0.6.1 - version: 0.6.1(vite@5.4.11(@types/node@22.10.7)) + version: 0.6.1(vite@5.4.19(@types/node@22.10.7)) vitepress: specifier: ^1.6.3 version: 1.6.3(@algolia/client-search@5.20.0)(@types/node@22.10.7)(async-validator@4.2.5)(postcss@8.5.1)(search-insights@2.17.3)(typescript@5.7.3) @@ -767,6 +770,9 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} + '@types/chrome@0.2.0': + resolution: {integrity: sha512-K/i7EKEVSpmyXXjE0ev5oASWBYMY6yM8LFSutG2PkM1DmxJUggZsoaTc0W1RsVwDDKrsZEjpHFAbqqxlRxGsSg==} + '@types/crypto-js@4.2.2': resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} @@ -3842,68 +3848,6 @@ packages: peerDependencies: vite: '>=2.0.0' - vite@5.4.11: - resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vite@5.4.14: - resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - vite@5.4.19: resolution: {integrity: sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -4688,6 +4632,11 @@ snapshots: '@trysound/sax@0.2.0': {} + '@types/chrome@0.2.0': + dependencies: + '@types/filesystem': 0.0.36 + '@types/har-format': 1.2.16 + '@types/crypto-js@4.2.2': {} '@types/debug@4.1.12': @@ -4811,14 +4760,9 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-vue@5.2.1(vite@5.4.11(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3))': - dependencies: - vite: 5.4.11(@types/node@22.10.7) - vue: 3.5.13(typescript@5.7.3) - - '@vitejs/plugin-vue@5.2.1(vite@5.4.14(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3))': + '@vitejs/plugin-vue@5.2.1(vite@5.4.19(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3))': dependencies: - vite: 5.4.14(@types/node@22.10.7) + vite: 5.4.19(@types/node@22.10.7) vue: 3.5.13(typescript@5.7.3) '@volar/language-core@2.4.11': @@ -8000,7 +7944,7 @@ snapshots: - supports-color - terser - vite-plugin-imagemin@0.6.1(vite@5.4.11(@types/node@22.10.7)): + vite-plugin-imagemin@0.6.1(vite@5.4.19(@types/node@22.10.7)): dependencies: '@types/imagemin': 7.0.1 '@types/imagemin-gifsicle': 7.0.4 @@ -8025,28 +7969,10 @@ snapshots: imagemin-webp: 6.1.0 jpegtran-bin: 6.0.1 pathe: 0.2.0 - vite: 5.4.11(@types/node@22.10.7) + vite: 5.4.19(@types/node@22.10.7) transitivePeerDependencies: - supports-color - vite@5.4.11(@types/node@22.10.7): - dependencies: - esbuild: 0.21.5 - postcss: 8.5.1 - rollup: 4.30.1 - optionalDependencies: - '@types/node': 22.10.7 - fsevents: 2.3.3 - - vite@5.4.14(@types/node@22.10.7): - dependencies: - esbuild: 0.21.5 - postcss: 8.5.1 - rollup: 4.30.1 - optionalDependencies: - '@types/node': 22.10.7 - fsevents: 2.3.3 - vite@5.4.19(@types/node@22.10.7): dependencies: esbuild: 0.21.5 @@ -8065,7 +7991,7 @@ snapshots: '@shikijs/transformers': 2.1.0 '@shikijs/types': 2.1.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.2.1(vite@5.4.14(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3)) + '@vitejs/plugin-vue': 5.2.1(vite@5.4.19(@types/node@22.10.7))(vue@3.5.13(typescript@5.7.3)) '@vue/devtools-api': 7.7.1 '@vue/shared': 3.5.13 '@vueuse/core': 12.5.0(typescript@5.7.3) @@ -8074,7 +8000,7 @@ snapshots: mark.js: 8.11.1 minisearch: 7.1.1 shiki: 2.1.0 - vite: 5.4.14(@types/node@22.10.7) + vite: 5.4.19(@types/node@22.10.7) vue: 3.5.13(typescript@5.7.3) optionalDependencies: postcss: 8.5.1