From 6d5c843e1067060aae9a0ac61a4ed45fd2c573e2 Mon Sep 17 00:00:00 2001 From: foxhui Date: Mon, 16 Feb 2026 14:17:30 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20DeepSeek=20?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E9=80=82=E9=85=8D=E5=99=A8=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=B8=8D=E5=88=B0=E7=BB=93=E6=9E=9C=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20(closes=20#16)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 ++ src/backend/adapter/deepseek_text.js | 101 +++++++++++---------------- 2 files changed, 45 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd2d870..d7dbb50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.5.3] - 2026-02-16 + +### 🐛 Fixed +- **适配器** + - 修复 DeepSeek 文本生成适配器因接口格式更新导致无法获取生成结果 + ## [3.5.2] - 2026-02-10 ### 🐛 Fixed diff --git a/src/backend/adapter/deepseek_text.js b/src/backend/adapter/deepseek_text.js index 14a8614..2ecbbf1 100644 --- a/src/backend/adapter/deepseek_text.js +++ b/src/backend/adapter/deepseek_text.js @@ -108,9 +108,7 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) { let textContent = ''; let isComplete = false; - let responseFragmentIndex = -1; // RESPONSE 类型 fragment 的数组索引 - let currentFragmentIndex = -1; // 当前正在追加内容的 fragment 数组索引 - let fragmentCount = 0; // fragments 数组的当前长度 + let isCollecting = false; // 当前最后一个 fragment 是否为 RESPONSE 类型 const responsePromise = page.waitForResponse(async (response) => { const url = response.url(); @@ -132,50 +130,16 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) { try { const data = JSON.parse(dataStr); - // 初始响应中可能已有 fragments (如 SEARCH) + // --- 处理 fragment 列表变更,更新 isCollecting 状态 --- + + // 初始响应中可能已有 fragments (如 SEARCH / RESPONSE) if (data.v?.response?.fragments && Array.isArray(data.v.response.fragments)) { for (const fragment of data.v.response.fragments) { - const idx = fragmentCount++; if (fragment.type === 'RESPONSE') { - responseFragmentIndex = idx; - currentFragmentIndex = idx; - if (fragment.content) { - textContent += fragment.content; - } + isCollecting = true; + if (fragment.content) textContent += fragment.content; } else { - currentFragmentIndex = idx; - } - } - } - - // 简单的文本追加 (只有 v 字符串,没有 p 和 o) - // 只有当前活跃的 fragment 是 RESPONSE 类型时才收集 - if (data.v && typeof data.v === 'string' && !data.p && !data.o) { - if (currentFragmentIndex === responseFragmentIndex && responseFragmentIndex >= 0) { - textContent += data.v; - } - } - - // 带路径的 APPEND 操作 (如 response/fragments/1/content) - if (data.o === 'APPEND' && data.p && typeof data.v === 'string') { - const match = data.p.match(/response\/fragments\/(\d+)\/content/); - if (match) { - const fragIdx = parseInt(match[1], 10); - currentFragmentIndex = fragIdx; - if (fragIdx === responseFragmentIndex) { - textContent += data.v; - } - } - } - - // 不带操作符的路径设置 (如 {"v": "xxx", "p": "response/fragments/1/content"}) - if (data.p && typeof data.v === 'string' && !data.o) { - const match = data.p.match(/response\/fragments\/(\d+)\/content/); - if (match) { - const fragIdx = parseInt(match[1], 10); - currentFragmentIndex = fragIdx; - if (fragIdx === responseFragmentIndex) { - textContent += data.v; + isCollecting = false; } } } @@ -183,16 +147,11 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) { // fragments APPEND - 新增 fragment (非 BATCH) if (data.p === 'response/fragments' && data.o === 'APPEND' && Array.isArray(data.v)) { for (const fragment of data.v) { - const idx = fragmentCount++; if (fragment.type === 'RESPONSE') { - responseFragmentIndex = idx; - currentFragmentIndex = idx; - if (fragment.content) { - textContent += fragment.content; - } + isCollecting = true; + if (fragment.content) textContent += fragment.content; } else { - // THINK 或 SEARCH - currentFragmentIndex = idx; + isCollecting = false; } } } @@ -200,28 +159,46 @@ async function generate(context, prompt, imgPaths, modelId, meta = {}) { // BATCH 操作中的 fragments if (data.o === 'BATCH' && data.p === 'response' && Array.isArray(data.v)) { for (const item of data.v) { - // fragments 追加 if (item.p === 'fragments' && item.o === 'APPEND' && Array.isArray(item.v)) { for (const fragment of item.v) { - const idx = fragmentCount++; if (fragment.type === 'RESPONSE') { - responseFragmentIndex = idx; - currentFragmentIndex = idx; - if (fragment.content) { - textContent += fragment.content; - } + isCollecting = true; + if (fragment.content) textContent += fragment.content; } else { - // THINK 或 SEARCH - currentFragmentIndex = idx; + isCollecting = false; } } } - // 检查是否完成 - if (item.p === 'status' && item.v === 'FINISHED') { + // 检查是否完成 (quasi_status 或 status) + if ((item.p === 'status' || item.p === 'quasi_status') && item.v === 'FINISHED') { isComplete = true; } } } + + // --- 处理文本内容追加 --- + + // 带路径的 content 操作 (如 response/fragments/-1/content) + if (data.p && typeof data.v === 'string') { + const match = data.p.match(/response\/fragments\/(-?\d+)\/content/); + if (match && isCollecting) { + textContent += data.v; + } + } + + // 纯文本追加 (只有 v 字符串,没有 p 和 o) + if (data.v && typeof data.v === 'string' && !data.p && !data.o) { + if (isCollecting) { + textContent += data.v; + } + } + + // --- 检查完成信号 --- + + // 独立的 status SET 操作 + if (data.p === 'response/status' && data.o === 'SET' && data.v === 'FINISHED') { + isComplete = true; + } } catch { // 忽略解析错误 }