Skip to content

建议:给阅读页加一层「思考链 / 回答」实时翻译(对标 dsh-think-translate) #62

Closed

Description

@lin636

先说好的地方:阅读页把过程收起来、思考卡自己跟着滚动、折叠的节奏(收缩→计数→停顿→继续)都很克制,动效和排版是这套插件里最难被替代的部分。也正因为这样,我下面这个建议才不敢自己乱做。

(以下为原话,未做任何改写,本 issue 中仅此一段是用户原话)

插件确实美观好看,缺翻译,能不能加入类似这个插件的效果,我让ai花点时间倒是也能适配,但是做出来没您好看

想要的

  • 翻译思考链(reasoning 块)和最终回答,最好连任务卡 / 待办也一起。
  • 对标 dsh-think-translate:8 种目标语言、边流边翻(按句成批)、纯展示层——原文仍留在 transcript 和模型上下文里,翻译文本不进 context。
  • 代码、路径、命令、URL 不翻。
  • 默认关,设置里 opt-in。这一点和 DESIGN.md 的「Preserve literal reasoning text, whitespace, source order and block identity」是一致的,我不想让默认行为变味。

为什么现在没有:两个插件占的是不同的层

  • dsh-think-translate 是替换官方 assistant-step 节点渲染器(conversation.chat.node / key assistant-step / priority -1,压过官方的 priority 0),它自己的 ThinkRow 负责翻译版思考行。
  • dsh-better-display 是替换整个会话视图(conversation.view / id reader / order -5),并且在 installOfficialSlots 里把官方节点镜像到自己的 seat,其中 READER_NODES = ['user','steering','assistant-step','tool-call','turn-tail','turn-process'] 是排除的——因为这些行由阅读页自己画。

结果就是:进阅读页之后,思考块由 ReadingReasoning 渲染,think-translate 的渲染器根本没机会跑。所以这不是「装两个插件就行」,是阅读页这一层缺一个接缝。

(复现环境:DSH 0.2.0-rc.2 / dsh-better-display 0.3.6 / dsh-think-translate 1.2.7,两个插件同时安装、都启用。)

为什么「自己适配」做出来会差一档(技术原因,也是我建议的最小接入面)

阅读页的观感和文本是绑在一起的:

  • lib/types/client/Blocks.js:81 的 ReadingReasoning({ text, streaming, holdFormatting, startedAt, interrupted, liveText }) 先过 useStreamingText(...),再由 MotionPlainText 做 opacity/blur 逐字浮现;
  • 思考卡的跟随滚动在 ReasoningCard.js(reasoningTarget、REASON_STEP、两行步进、clamp 到真实末尾),DESIGN.md 里写的是 840ms 步进 / 500ms cubic-bezier(.22,1,.36,1) / 28px 视口遮罩。

而现有的扩展点 dsh-better-display.block(kind: 'chain')传给注册者的 owner 只有 { block, streaming, source },不带 presentation / holdFormatting / liveText。第三方一旦替换渲染,就等于自己重画,逐字浮现、跟随滚动、折叠编排全丢——这就是「做出来没您好看」的技术原因,不是手艺问题。

所以建议二选一,推荐 (a):

  • (a) 文本变换缝:在 ReadingReasoning / ReadingMarkdown 进入 useStreamingText 之前留一个可选变换(例如 ctx 注入的 translation 服务,或 reader.text.transformer),返回 { text, final }。翻译只发生在展示层,block、session 数据和折叠生命周期都不动;阅读页保留全部动效与跟随,观感天然一致。
  • (b) 扩展 block slot 的 owner:把 presentation / holdFormatting / liveText 一起传下去,让第三方渲染器能复用同一套 reveal 机制。

两个都要注意的流式细节:

  • reasoning 是增量文本,翻译必须按句批处理并留「尾随边距」(think-translate 用的是 120 字符边距、最小批 24 字符、单批 900 字符),否则会翻到半句话;
  • 需要独立的翻译 revision,别挂在原文 revision 上,不然每来一句就重播一次浮现动画;
  • 引擎可以复用:think-translate 的翻译是 HTTP 路由 /_xlate/translate,provider 链是 google gtx / bing / 本地 Ollama / OpenAI 兼容 / Anthropic,外加 600 条 LRU 缓存,和渲染完全解耦。也就是说「用它的引擎 + 您的渲染」是可行的,不一定非要它再注册一个块渲染器。

最低成本方案

如果暂时没时间做翻译,那只要把 dsh-better-display.block 的契约写进 DESIGN.md、并按 (b) 补上 presentation 字段,社区就能自己接。对作者来说改动很小,对观感的保护最大。

附:设置项建议

建议在设置里加一节「翻译」:语言可以跟随现有 locale.register('better-display', { zh, en }) 的设置面板,或独立选择目标语言;默认关闭。


English summary (full text above is authoritative): the Reader view replaces the whole conversation view and renders reasoning itself (ReadingReasoning), while dsh-think-translate replaces the official conversation.chat.node / assistant-step renderer — so translation never runs inside the Reader. Suggested seam: an optional text-transform hook applied before useStreamingText, returning { text, final }, keeping the plugin's motion/fold/follow machinery intact; alternatively widen the dsh-better-display.block chain-slot owner with presentation / holdFormatting / liveText.

Activity

  1. added a commit that references this issue on Oct 26, 2026
  2. added a commit that references this issue on Oct 26, 2026
  3. aa2246740 commented on Oct 26, 2026

    @aa2246740
    Owner

    已通过 #76 合进 main,会随下一个版本发布。阅读页新增了一个只改显示的文本转换接口 dsh-better-display.text-transform:别的插件可以在阅读页显示之前改写思考链和回答的文字,比如翻译。会话、记录和折叠都还用原文,复制回答拿到的也是原文。转换插件出错时退回显示原文。用法见 docs/extension-points.md。

  4. LingMoe404 commented on Oct 29, 2026

    @LingMoe404
    Contributor

    顺着 #76 的结论补一个实现:我把「官方 COT 翻译 → 阅读页」的适配做成了独立插件,用的就是这个 dsh-better-display.text-transform 缝,没有改 better-display 的代码。

    仓库:https://github.com/LingMoe404/dsh-cot-translation-reader

    做法:

    • 注册 reasoning transformer;read 保持同步,只返回缓存或 undefined,真正的请求排进微任务;批次完成后用 subscribe 通知阅读页重绘。
    • 译文来自官方组合包的 ctx.cotTranslation:limits() 拿目标语言与单次上限,translate() 逐段请求,不复制翻译逻辑。
    • 只翻已经完成的段落,流式中的末段保持原文;段落超过单次上限时按空白切分,只翻已完成的前缀。
    • 译文按 blockKey 缓存,源文本变长时不会重复请求已经翻好的片段。
    • 失败返回 undefined,阅读页保留原文,只在控制台 warn;卸载时 abort 进行中的请求。

    前提:dsh-better-display ≥ 0.3.9(0.3.8 还没有这个缝),以及官方 @deepseek-ai/dsh-experimental-cot-translation-bundle。两个依赖缺任意一个时插件安静地不生效,不报错也不改界面。

    安装(已发布到 npm,当前 0.1.1):

    pnpm add dsh-cot-translation-reader

    不想等发版、要跟 main 的话,也可以从 GitHub 装:

    pnpm add github:LingMoe404/dsh-cot-translation-reader

    然后把 dsh-cot-translation-reader 加进 profile package.json 的 dsh.profile.bundles,重启 DSH 即可。

    这里只是给需要的人一个可运行的参考;如果更希望它作为 examples/ 里的示例存在,我可以整理一份提交 PR。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions