跳到主要内容

dsh-chat-translate

已验证

@lynn123411/dsh-chat-translate · v3.3.0 · MIT · Web 界面

Assistant reply-body translation for the DeepSeek Harness Web UI (OpenAI-compatible channel)

安装

dsh plugin add @lynn123411/dsh-chat-translate

用 dsh --profile default --dump-config 确认 layer 已生效 —— 参见安装指南。

源码

发布到 npm 但没有公开仓库。安装前请检查包内容。

标签

说明文档

@lynn123411/dsh-chat-translate

DeepSeek Harness Web 界面的助手回答正文翻译插件。它接管助手行的渲染:正文块不论源语言,一律送翻译模型加工成自然简体中文(如 I traced the failing path to a stale lock file. → 中文;模型写出的生硬机器腔中文同样送一遍润色——弱模型的中文恰恰最需要加工),译文按原 markdown 结构重新渲染。只翻正文:Think 卡的思考链、工具调用行、用户消息、代码块、空白块不动。正文块的左缘竖线报出状态:译文蓝粗线、备着译文的原文灰细线、失败红实线(悬停报通道细节:超时、断流、空返回)、在途灰脉动、没送过模型无线。切换与补跑都在贴着那条线的窄带上(鼠标移上去变手型,点一下切双语;挂红线的块点它手动补跑),正文整块不再响应点击——选中文字、拖选复制都不会误触。不污染会话上下文。开关有两个入口:输入框下方那一行的「译」胶囊与本插件配置页的总开关,同一个状态两处同步。配置详见 docs/配置.md。

特性

  • 接管助手行渲染:经 keyed slot conversation.chat.node(key assistant-step,priority -1)替换宿主的助手行渲染器。正文块从数据层拿原始 markdown(AssistantBlock.text),译文同样以 markdown 交给宿主公开的基线组件 MarkdownText(micromark + GFM + KaTeX)重渲染——表格、列表、加粗、行内代码、公式的结构由官方渲染器保证,插件不自拼 markup。接管渲染器抛错时按框架退位规则退出该 cell,宿主原渲染器自动回位。
  • 一律送译,不判源语言:正文的每一块都进模型,包括整段中文、纯数字、纯标点的块;只有 trim 后为空的块不送译、永不挂线(它没送过模型,重试也永远不会成,挂线只会留下消不掉的标记)。提示词要求模型把每一段都改写成自然、地道的简体中文——意义、语气、专名、数字与术语不动,不增不删;同时要求 markdown 记号原样保留。模型判断某段已经最好而返回一模一样的文字时,同样算翻译过、同样挂线(标记传达的是「这段过了模型」)。
  • 除正文外与宿主逐分支等价:Think 折叠行(含工作细节策略下的摘要预览、Turn-process 折叠隐藏与页内搜索揭示)、连续图片组交回宿主渲染、工具调用行由宿主独立渲染、未知内容块落 JSON 展示、中断前缀行尾带「已停止」——这些 chrome 文案复用宿主 chat 词典,两侧逐字一致。
  • 左缘竖线报状态,贴着线的那条窄带才可点:显示译文为 1px 主色蓝线、点回原文为 0.5px 中性灰线(留有译文、可再点回的线索)、失败一律为 1px error 色红实线(不分败因——区别在悬停文案里说清)、在途为灰线脉动、没送过模型无线(区分走色相与粗细)。可点的是左缘那条约 17px 的窄带(线外侧 4px + 线 + 线内侧那 12px 缩进,随块高铺满),不是正文:鼠标移上去变手型,点一下即操作——成功的块在译文与原文间切换,失败的块发起手动补跑,块与块互不影响,关闭开关即全部回到原文、线全部撤下。悬停不改任何视觉,只有键盘聚焦时线加亮(粗细始终只表示译文/原文);正文整块不响应点击,拖选复制不再误触切换。可翻译时(开关开 + 通道齐备)所有正文块统一左缩进 12px,译文落定时正文不跳字;关掉开关或通道没配好则不缩进,排版回到宿主原样。
  • 落定才翻、进视口才翻:回答流式期间整行按原文渲染;data-streaming 落定且行进入视口(150px 缓冲)后,整行正文按估算 token 预算切批、逐批顺序请求——先回的段先出中文,按阅读顺序逐段呈现。历史会话因此只在真的被读到时才花请求。这是每行的首跑,也是唯一自动发生的请求。
  • 失败只有一种:通道伤:块级失败不进缓存、保持原文,左缘挂红实线,悬停左缘那条窄带报出通道细节(超时、断流、空返回)。译文的结构漂移不再是失败理由(见下条)。红线块右侧常驻一个小 ↻,点那条窄带即整行手动补跑,已成功的块保持挂线展示(宿主磁盘缓存让它们秒回,不花模型调用),只有尚无译文的块重新脉动;在途时窄带仍在(键盘焦点不掉)但按下去是空操作,光标也不再变手型。通道失败不自动重试:一行首跑一次,落定即终态,救活由用户发起。失败仍在控制台留一条警告。
  • 按行幂等的翻译池:客户端按会话锚点键登记整行结果,同文本重复渲染不重发请求;行内容换代则整行重译,迟到的旧代结果作废。
  • 结构重装配,形状问题只修不拒:宿主先把块按 markdown 结构切段——代码围栏与纯空白段逐字保留、永不送模型——散文段再按输入上限切片(单段超限按空行、单行、句末切开)、相邻片段打包成一个请求(输入上限 4096 估算 token、输出上限 8192 token)。回来的译文过形状修复(repairShape):按段落块对齐,块内结构行(记号类别、表格竖线数、链接个数、缩进代码缩进)逐一对齐并把行首前缀修回原文同款(##→###、-→*、序号、引用深度、列表缩进的漂移就此消失),散文行自由重排(软换行渲染无感),空行布局一律取原文,[文字](URL) 的 URL 按出现序逐字拼回。修不齐的片段自动重掷一次;仍不齐就照收模型的译文——原文一键可回,可读的译文优先于红线。反引号、行内代码内容一律不拦:是样式不是骨架。
  • 单通道:AI 翻译(OpenAI 兼容协议):对接任意 OpenAI 兼容的 chat/completions 服务(OpenAI、DeepSeek、通义、Ollama、本地 vLLM 等)。Key / Base URL / 模型三者齐备才翻译,缺任何一项保持原文,不做降级兜底。API Key 经 DSH 凭据服务读写 ~/.dsh/.credentials.yaml 的 TRANSLATE_API_KEY;Base URL 与模型在本插件的配置页配置。
  • 串行与超时:同时最多一个在途请求,单次超时 aiTimeoutMs(默认 600000 毫秒,范围 500–900000)——每行首跑与每次手点都等到真实结果,嫌等就把超时调小。磁盘缓存池 ~/.dsh/dsh-chat-translate/cache.json(7 天 TTL、1000 条 LRU)按提示词修订号整体作废:文档里登记 rev,换提示词语义后旧译文不会串代。
  • 跟随宿主显示设置:Think 行的折叠摘要预览跟随「工作细节」模式(读 ui-chat 配置的 transcriptView,含 legacy 取值映射);设置缺席时按 standard。
  • DSH 原生配置接入:配置就是本插件在 profile 里的插件配置——配置页经 ctx.configForms 读写条目 dsh-chat-translate 的 config,用户层落在当前 profile 的 patch;无任何自研配置文件,译文从不写回会话上下文。
  • 配置页挂在宿主「插件」页:配置卡片注册进 plugins.bundle.config(key 为包名 @lynn123411/dsh-chat-translate),路径是「插件」→本插件详情页 —— 配置直接铺在描述之下、行列表之上。页面由宿主画标题、图标与面包屑,卡片提供总开关、API Key、Base URL、模型、单次请求超时与「测试 AI 通道」;设置页里不再有任何本插件的入口。做法与约束见仓库 docs/rules/plugin-config-page.md。

安装

dsh plugin --profile web add @lynn123411/dsh-chat-translate