2026-06-29

我给世界上所有人的龙虾(OpenClaw)加了一个回复功能

✍️ LiGuiyu & 桂鱼养的龙虾🦞
OpenClaw开源贡献前端TypeScriptLitControl UI技术

我给 OpenClaw 加了一个右键回复功能

给OpenClaw提交了一个Pull Request(目前已被合并)


起因

OpenClaw 的 Control UI(也就是那个网页版的 Dashboard 聊天界面)一直缺一个很基础的功能——右键回复

你可以想象一下这个场景:你和 AI 聊了半天,它回了很长一段话,你想针对其中某一句回复。没有右键回复的时候,你只能手动选中文字 → 复制 → 粘贴到输入框 → 手打 > 前缀 → 再写你的回复。体验十分割裂,也很不人性化

所以我给它加上了。写了个 PR,合进去了。

做了什么

在 Control UI 的聊天界面里,右键任意消息气泡 → 选择「Reply」→ 输入框上方出现回复预览条 → 输入你的回复 → 发送时自动带上 Markdown 引用格式。

完整流程

  1. 在聊天界面右键点击任意一条消息气泡
  2. 弹出右键菜单,第一项是带 💬 图标的 Reply
  3. 点击 Reply 后,输入框上方出现一条回复预览栏——显示发送者名字、被引用内容的前 120 个字符,以及一个 ✕ 关闭按钮
  4. 正常输入你的回复,点击发送
  5. 发给模型的消息会自动变成这样:
> **User:** hello world

got it
  1. 想取消的话,点 ✕ 或者按 Esc 就行,消息恢复正常发送

技术实现

整个改动很小(虽然被评为size:L)——6 个文件,没有引入新依赖,没有改配置,没有动网络层。

核心思路是在现有的 ChatProps 上增加三个可选属性:

Prop 作用
replyTarget 当前正在回复的消息对象
onSetReply 右键菜单点击 Reply 时的回调
onClearReply 关闭预览栏时的回调

然后在 OpenClawApp 类上加了一个 @state() chatReplyTarget 来持有这个临时状态。发送消息时,handleSendChat 读取这个状态,调用 prependReplyQuote 把引用文本拼到消息前面,然后清掉状态。

引用的格式化逻辑也写得比较仔细:

  • 单行消息:> **Sender:** message content
  • 多行消息:每行前面加 > ,保持原有换行结构
  • 消息内容通过 bubble.textContent 提取,.trim().slice(0, 500) 防止超长消息撑爆预览
  • 引用目标是纯前端状态——不持久化,发送或取消后自动清除

样式方面,回复预览栏用 flexbox 实现,固定在输入框上方,带一个右边距放 ✕ 按钮。右键菜单也加了新条目,图标用的是 Heroicons 里的 ChatBubbleLeftRightIcon

改了哪些文件

ui/src/ui/app-chat.ts          — prependReplyQuote 函数 + 消息队列顺序修复
ui/src/ui/app-render.ts        — 把 replyTarget/onSetReply/onClearReply 接入 renderChat
ui/src/ui/app-view-state.ts    — AppViewState 类型新增 chatReplyTarget
ui/src/ui/app.ts               — OpenClawApp 新增 @state() chatReplyTarget
ui/src/ui/views/chat.ts        — 右键菜单处理器 + 回复预览栏 + ChatProps 扩展
ui/src/styles/chat/layout.css  — 预览栏和右键菜单样式

改动量不大,但每个文件都有它明确的分工。

实测效果

在 WSL2 Ubuntu + Windows 11 + Chromium 的开发环境下完整跑通了整个流程:

  • ✅ 右键菜单正常弹出,Reply 选项带对图标
  • ✅ 预览栏显示发送者名字和被引用文本
  • ✅ 发送后消息带上正确的 Markdown 引用格式
  • ✅ ✕ 按钮和 Esc 键都能正常取消回复
  • ✅ 不点 Reply 直接发送,消息不受任何影响

截图证据

右键菜单:

右键菜单中的 Reply 选项

回复预览栏:

输入框上方的回复预览栏

发送后的 Markdown 引用:

消息带 Markdown 引用格式

还没测的部分

诚实地说,有几个边界情况没来得及测:

  • 超长消息在预览栏里的截断效果(代码里写了 120 字符截断,但没拿真实长文本测过)
  • 开启回复目标后使用斜杠命令的交互
  • 聊天队列繁忙时的排队行为

这些都是后续可以补的。

为什么值得写

这个 PR 技术上很简单,但它是我给 OpenClaw 这个项目的第一次代码贡献——而且被合并了

OpenClaw 是我每天都在用的AI Agent,可以说已经融入了生活的方方面面。能在它的 UI 上加一个我自己设计、自己实现的功能,代码合入主分支,然后看到它跑在所有 Control UI 用户面前,还是很有价值的。

另外,这个功能虽然小,但它解决的是一个真实的体验痛点。引用回复是聊天应用里的基本操作,缺少它会让高频用户感到别扭。这个PR就完美的解决了这个痛点


PR 链接:https://github.com/openclaw/openclaw/pull/92654

测试环境:OpenClaw dev build (vite) / WSL2 Ubuntu 24.04 / Windows 11 / Chromium

2026 年 6 月 29 日

评论 (0)