@lynn123411/dsh-chat-translate 3.0.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,19 +1,19 @@
1
1
  # @lynn123411/dsh-chat-translate
2
2
 
3
- DeepSeek Harness Web 界面的**助手回答正文翻译**插件。它接管助手行的渲染:正文块不论源语言,一律送翻译模型加工成自然简体中文(如 `I traced the failing path to a stale lock file.` → 中文;模型写出的生硬机器腔中文同样送一遍润色——弱模型的中文恰恰最需要加工),译文按原 markdown 结构重新渲染。只翻正文:Think 卡的思考链、工具调用行、用户消息、代码块不动。已翻译的块左缘竖线:译文蓝粗线、原文灰细线、未译无线。不污染会话上下文。开关有两个入口:输入框下方那一行的「译」胶囊与共享「阅读体验」设置页的总开关,同一个状态两处同步。配置详见 [docs/配置.md](./docs/配置.md)。
3
+ DeepSeek Harness Web 界面的**助手回答正文翻译**插件。它接管助手行的渲染:正文块不论源语言,一律送翻译模型加工成自然简体中文(如 `I traced the failing path to a stale lock file.` → 中文;模型写出的生硬机器腔中文同样送一遍润色——弱模型的中文恰恰最需要加工),译文按原 markdown 结构重新渲染。只翻正文:Think 卡的思考链、工具调用行、用户消息、代码块、空白块不动。正文块的左缘竖线报出状态:译文蓝粗线、备着译文的原文灰细线、失败红实线(悬停报通道细节:超时、断流、空返回)、在途灰脉动、没送过模型无线;成功的块点击切双语,失败的块点击即手动补跑。不污染会话上下文。开关有两个入口:输入框下方那一行的「译」胶囊与共享「阅读体验」设置页的总开关,同一个状态两处同步。配置详见 [docs/配置.md](./docs/配置.md)。
4
4
 
5
5
  ## 特性
6
6
 
7
7
  - **接管助手行渲染**:经 keyed slot `conversation.chat.node`(key `assistant-step`,priority -1)替换宿主的助手行渲染器。正文块从数据层拿**原始 markdown**(`AssistantBlock.text`),译文同样以 markdown 交给宿主公开的基线组件 `MarkdownText`(micromark + GFM + KaTeX)重渲染——表格、列表、加粗、行内代码、公式的结构由官方渲染器保证,插件不自拼 markup。接管渲染器抛错时按框架退位规则退出该 cell,宿主原渲染器自动回位。
8
- - **一律送译,不判源语言**:正文的每一块都进模型,包括整段中文、纯数字、纯标点的块。提示词要求模型把每一段都改写成自然、地道的简体中文——意义、语气、专名、数字与术语不动,不增不删;同时要求 markdown 记号原样保留。模型判断某段已经最好而返回一模一样的文字时,同样算翻译过、同样挂线(标记传达的是「这段过了模型」)。
8
+ - **一律送译,不判源语言**:正文的每一块都进模型,包括整段中文、纯数字、纯标点的块;只有 trim 后为空的块不送译、永不挂线(它没送过模型,重试也永远不会成,挂线只会留下消不掉的标记)。提示词要求模型把每一段都改写成自然、地道的简体中文——意义、语气、专名、数字与术语不动,不增不删;同时要求 markdown 记号原样保留。模型判断某段已经最好而返回一模一样的文字时,同样算翻译过、同样挂线(标记传达的是「这段过了模型」)。
9
9
  - **除正文外与宿主逐分支等价**:Think 折叠行(含工作细节策略下的摘要预览、Turn-process 折叠隐藏与页内搜索揭示)、连续图片组交回宿主渲染、工具调用行由宿主独立渲染、未知内容块落 JSON 展示、中断前缀行尾带「已停止」——这些 chrome 文案复用宿主 `chat` 词典,两侧逐字一致。
10
- - **已翻译标记与双语切换**:已翻译的块左缘一条竖线——显示译文为 1px 主色蓝线、点回原文为 0.5px 中性灰线(留有译文、可再点回的线索;0.5px 上虚线会被抗锯齿糊平,区分走色相与粗细),未译成则无线;整块可点击(键盘 Enter/Space 同样)在译文与原文间切换,块与块互不影响,关闭开关即全部回到原文。
11
- - **落定才翻、进视口才翻**:回答流式期间整行按原文渲染;`data-streaming` 落定且行进入视口(150px 缓冲)后,整行正文按估算 token 预算切批、逐批顺序请求——先回的段先出中文,按阅读顺序逐段呈现。历史会话因此只在真的被读到时才花请求。
12
- - **失败即原文,界面静默**:块级失败(通道错误、占位符被改写/遗失、空结果)不进缓存、不显示标记,保持原文;一批失败只败在这一批,含失败块的行停在待重试态,该行滚出视口再回来或重挂载时自然重走、同一代文本封顶三次(已成功的块由宿主磁盘缓存直接命中,不再花模型调用)。控制台留一条警告。
10
+ - **左缘竖线报状态,点击即操作**:显示译文为 1px 主色蓝线、点回原文为 0.5px 中性灰线(留有译文、可再点回的线索)、失败一律为 1px error 色红实线(不分败因——区别在悬停文案里说清)、在途为灰线脉动、没送过模型无线(区分走色相与粗细)。有蓝灰红线的块整块可点击(键盘 Enter/Space 同样):成功的块在译文与原文间切换,失败的块发起手动补跑,块与块互不影响,关闭开关即全部回到原文、线全部撤下。
11
+ - **落定才翻、进视口才翻**:回答流式期间整行按原文渲染;`data-streaming` 落定且行进入视口(150px 缓冲)后,整行正文按估算 token 预算切批、逐批顺序请求——先回的段先出中文,按阅读顺序逐段呈现。历史会话因此只在真的被读到时才花请求。这是每行的首跑,也是唯一自动发生的请求。
12
+ - **失败只有一种:通道伤**:块级失败不进缓存、保持原文,左缘挂红实线,悬停报出通道细节(超时、断流、空返回)。译文的结构漂移不再是失败理由(见下条)。红线块可点:整行手动补跑,已成功的块保持挂线展示(宿主磁盘缓存让它们秒回,不花模型调用),只有尚无译文的块重新脉动;在途时再点是空操作。通道失败不自动重试:一行首跑一次,落定即终态,救活由用户发起。失败仍在控制台留一条警告。
13
13
  - **按行幂等的翻译池**:客户端按会话锚点键登记整行结果,同文本重复渲染不重发请求;行内容换代则整行重译,迟到的旧代结果作废。
14
- - **打包请求与脱敏保护**:宿主把相邻块打包成一个请求(输入上限 4096 估算 token、输出上限 8192 token),单块超限按空行、单行、句末切开再拼回;翻译前对代码块、内联代码、URL、文件路径、CLI 参数做 `⟦…⟧` 占位符脱敏,译文必须逐位原样带回占位符,否则整块作废、绝不入缓存。
14
+ - **结构重装配,形状问题只修不拒**:宿主先把块按 markdown 结构切段——代码围栏与纯空白段**逐字保留、永不送模型**——散文段再按输入上限切片(单段超限按空行、单行、句末切开)、相邻片段打包成一个请求(输入上限 4096 估算 token、输出上限 8192 token)。回来的译文过**形状修复**(`repairShape`):按段落块对齐,块内结构行(记号类别、表格竖线数、链接个数、缩进代码缩进)逐一对齐并把行首前缀修回原文同款(`##`→`###`、`-`→`*`、序号、引用深度、列表缩进的漂移就此消失),散文行自由重排(软换行渲染无感),空行布局一律取原文,`[文字](URL)` 的 URL 按出现序逐字拼回。修不齐的片段自动重掷一次;仍不齐就照收模型的译文——原文一键可回,可读的译文优先于红线。反引号、行内代码内容一律不拦:是样式不是骨架。
15
15
  - **单通道:AI 翻译(OpenAI 兼容协议)**:对接任意 OpenAI 兼容的 `chat/completions` 服务(OpenAI、DeepSeek、通义、Ollama、本地 vLLM 等)。Key / Base URL / 模型三者齐备才翻译,缺任何一项保持原文,不做降级兜底。API Key 经 DSH 凭据服务读写 `~/.dsh/.credentials.yaml` 的 `TRANSLATE_API_KEY`;Base URL 与模型在设置面板配置。
16
- - **串行与熔断**:同时最多一个在途请求,单次超时 `aiTimeoutMs`(默认 600000 毫秒,范围 500–900000),连续传输失败熔断自愈——只数传输故障,内容级拒收(占位符没原样带回等)当场作废该块而不计入熔断账本,一段坏内容挡不住其他行。磁盘缓存池 `~/.dsh/dsh-chat-translate/cache.json`(7 天 TTL、1000 条 LRU)**按提示词修订号整体作废**:文档里登记 `rev`,换提示词语义后旧译文不会串代。
16
+ - **串行与超时**:同时最多一个在途请求,单次超时 `aiTimeoutMs`(默认 600000 毫秒,范围 500–900000)——每行首跑与每次手点都等到真实结果,嫌等就把超时调小。磁盘缓存池 `~/.dsh/dsh-chat-translate/cache.json`(7 天 TTL、1000 条 LRU)**按提示词修订号整体作废**:文档里登记 `rev`,换提示词语义后旧译文不会串代。
17
17
  - **跟随宿主显示设置**:Think 行的折叠摘要预览跟随「工作细节」模式(读 `ui-chat` 配置的 `transcriptView`,含 legacy 取值映射);设置缺席时按 standard。
18
18
  - **DSH 原生配置接入**:配置就是本插件在 profile 里的插件配置——设置面板经 `ctx.configForms` 读写条目 `dsh-chat-translate` 的 `config`,用户层落在当前 profile 的 patch;无任何自研配置文件,译文从不写回会话上下文。
19
19
  - **设置面板集成**:设置面板挂在「设置 - 阅读体验」页(本插件贡献其中一张卡片),页内提供总开关、API Key、Base URL、模型、单次请求超时与「测试 AI 通道」。
@@ -25,13 +25,13 @@
25
25
 
26
26
  目标语言固定为简体中文,没有配置项。
27
27
 
28
- 3. **翻译范围与时机**:插件接管助手行的渲染(keyed slot `conversation.chat.node` / `assistant-step`,priority -1)。正文块不论源语言一律送模型改写成自然简体中文——「用时 XXX」大折叠块里每一步露出的正文与最终汇总那一步一视同仁;整段中文同样照送(意义、术语、数字不动,顺掉机器腔)。模型返回与原文一模一样的文字时同样算翻译过:照常显示、照常可切换。左缘线的色相与粗细随显示态:显示译文挂 1px 主色蓝线(`--dsw-alias-state-business-primary` 65%),点回原文挂 0.5px 中性灰线(`--dsw-alias-border-l2`,备着译文、可点回),未译成无线——线宽只差 0.5px,切换不跳字。分组判据是座次传入的 `groupPart`(`response` 分组排除思考块,`reasoning` 分组只渲染思考块,不送译),流式判据是行数据的 `status === "running"`。流式期间整行按原文渲染;落定且该行进入视口(150px 缓冲)后,整行正文按估算 token 预算切批、逐批顺序请求,先回的段先出中文,不需要点任何按钮。
28
+ 3. **翻译范围与时机**:插件接管助手行的渲染(keyed slot `conversation.chat.node` / `assistant-step`,priority -1)。正文块不论源语言一律送模型改写成自然简体中文——「用时 XXX」大折叠块里每一步露出的正文与最终汇总那一步一视同仁;整段中文同样照送(意义、术语、数字不动,顺掉机器腔)。模型返回与原文一模一样的文字时同样算翻译过:照常显示、照常可切换。trim 后为空的块不送译、不占下标、永不挂线;块内的代码围栏逐字保留、从不送模型。左缘线的色相、线型与粗细随显示态:显示译文挂 1px 主色蓝线(`--dsw-alias-state-business-primary` 65%),点回原文挂 0.5px 中性灰线(`--dsw-alias-border-l2`,备着译文、可点回),失败一律挂 1px error 色红实线(`--dsw-alias-state-error-primary` 65%——只剩通道伤一种,悬停报细节),在途挂灰线脉动(`prefers-reduced-motion` 降级为静态),没送过模型无线;线宽之差亚像素级,切换不跳字。分组判据是座次传入的 `groupPart`(`response` 分组排除思考块,`reasoning` 分组只渲染思考块,不送译),流式判据是行数据的 `status === "running"`。流式期间整行按原文渲染;落定且该行进入视口(150px 缓冲)后,整行正文按估算 token 预算切批、逐批顺序请求,先回的段先出中文——这是每行的首跑,也是唯一自动发生的请求。
29
29
 
30
- - 不送译的内容:Think 卡的思考链正文、工具调用行、用户消息、代码块(`pre`)及其内部——这些与宿主渲染逐分支等价,接管渲染器抛错时按框架退位规则由宿主渲染器自动回位。
30
+ - 不送译的内容:Think 卡的思考链正文、工具调用行、用户消息、代码块(`pre`)及其内部、空白块——这些与宿主渲染逐分支等价,接管渲染器抛错时按框架退位规则由宿主渲染器自动回位。
31
31
  - 译文用宿主基线组件 `MarkdownText` 重新渲染,表格、列表、加粗、行内代码的结构保持原样。
32
- - 失败即保留原文:块内任一片段失败就整块按原文渲染、不挂线,界面上不留提示,控制台留一条警告;失败结果不进缓存,一批失败只败在这一批,含失败块的行停在待重试态——该行滚出视口再回来或重挂载时自然重走、同一代文本封顶三次(`MAX_ROW_ATTEMPTS`,换代重置),已成功的块由宿主磁盘缓存直接命中。熔断账本只数传输故障:占位符/块标记没原样带回属于内容级拒收,记通道可用、当场作废该块,一段弱模型啃不动的内容不会把其他行挡在冷却期外。
33
- - 点击翻译过的块在译文与原文间切换(键盘 Enter/Space 同样),块与块互不影响;关闭总开关即全部回到原文。
32
+ - 失败只有一种(通道伤)、悬停报细节,重试归手点:块内任一片段通道失败(超时、断流、空返回)就整块按原文渲染、挂 1px error 色红实线;悬停出 Tooltip 报服务端原样带回的技术一句(如展开后的 fetch 报错、`channel timed out after 20000ms`)。**译文的结构漂移不是失败理由**——它由形状修复消化(见下条),修不齐的自动重掷一次、仍不齐则照收,永不因格式挂红线。控制台各留一条通道失败警告。失败结果不进缓存,一批失败只败在这一批;通道失败**不自动重试**——滚动、重挂载都不会重发已落定的行,救活由点击发起:点任一红线块 = 整行手动补跑,无限次不设额度,已成功的块当场种回保持挂线(宿主磁盘缓存让它们秒回、不花模型调用),只有尚无译文的块重新脉动;在途再点是空操作。
33
+ - 点击翻译过的块在译文与原文间切换,点击挂红线的块补跑整行(键盘 Enter/Space 同样),块与块互不影响;关闭总开关即全部回到原文、线全部撤下。悬停或键盘聚焦失败块时,左缘线槽里露出小 ↻(官方 `IconRefreshOutlineRegular`),Tooltip 报的就是上述败因而非操作指引,屏幕阅读器读「翻译失败,按 Enter 重试」。
34
34
 
35
- 4. **请求方式**:按行请求——落定的助手行把它全部正文块一次送出,宿主把相邻块打包成一个请求(输入上限 4096 估算 token、输出上限 8192 token),单块超过输入上限时按空行、单行、句末依次切开,译回后拼回。同时最多一个在途请求,超时由 `aiTimeoutMs` 控制(默认 600000 毫秒,范围 500–900000)。客户端只保留一个按行的内存翻译池(会话锚点为键,LRU 200 行);持久缓存只有宿主的磁盘池 `~/.dsh/dsh-chat-translate/cache.json`(1000 条、7 天 LRU),文档形态是 `{ rev, entries }`,其中 `rev` 登记写入它的提示词修订号——修订号(`src/server/prompt-revision.ts` 的 `PROMPT_REVISION`,单点登记)与实际加载的提示词不符时整池作废重来,换提示词不会让旧译文串代。
35
+ 4. **请求方式**:按行请求——落定的助手行把它全部正文块一次送出。宿主先按 markdown 结构切段:代码围栏与纯空白段逐字保留、永不送模型;散文段超过输入上限(4096 估算 token)时按空行、单行、句末依次切开,相邻片段打包成一个请求(输出上限 8192 token),译回后按原结构拼回——片段头尾的空行由拆下的部分补回,`[文字](URL)` 的 URL 按出现序逐字拼回。每片段过**形状修复**(`repairShape`):按段落块对齐,块内结构行(记号类别、表格竖线数、链接个数、缩进代码缩进)逐一对齐并把行首前缀修回原文同款(标题层级、列表符号、序号、引用深度、列表缩进的漂移就此消失),散文行自由重排(软换行渲染无感、只查整块链接总数不丢),空行布局一律取原文。修不齐的片段自动重掷一次;仍不齐则照收模型的译文(链接数不等时不回填,其余原样)——形状问题永不否决内容,红线只留给通道伤。同时最多一个在途请求,超时由 `aiTimeoutMs` 控制(默认 600000 毫秒,范围 500–900000)——每行首跑与每次手点都等到真实结果,嫌等就调小超时。客户端只保留一个按行的内存翻译池(会话锚点为键,LRU 200 行);持久缓存只有宿主的磁盘池 `~/.dsh/dsh-chat-translate/cache.json`(1000 条、7 天 LRU),文档形态是 `{ rev, entries }`,其中 `rev` 登记写入它的提示词修订号——修订号(`src/server/prompt-revision.ts` 的 `PROMPT_REVISION`,单点登记)与实际加载的提示词不符时整池作废重来,换提示词不会让旧译文串代。
36
36
 
37
37
  5. **通道行为**:只有一条通道——Key / Base URL / 模型三者齐备才翻译,缺任何一项都保持原文,不做降级兜底。