Skip to content

feat(webui): QQ 式聊天页,打字和语音通话都是和机器人本人私聊 - #1231

Merged
SuInk merged 4 commits into
mainfrom
claude/voice-call-admin-chat
Oct 27, 2026
Merged

SuInk merged 4 commits into
mainfrom
claude/voice-call-admin-chat

Conversation

@SuInk

@SuInk SuInk commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

新增 QQ 式「聊天」页:左边是带头像的机器人列表,右边是和选中那台的私聊,打字和打电话都是跟机器人本人(人设、记忆)聊,平台上的私聊记录也在里面。语音通话从顶栏的独立测试页挪到聊天页右上角,点开是照手机通话做的全屏界面。管理对话保持原样,只是顶栏按钮再点一下能关掉。

Why

用户希望和机器人聊天、打电话「像 QQ 一样」:有好友列表、有头像、选机器人就能聊。上一版 #1211「feat(voice): 实时语音通话通道与网页测试页」只有一个顶栏通话测试页,打字没有入口。

一开始试过把电话塞进「管理对话」,但管理对话里是替主人干活的管理助手(有执行权限、用管理模型、不带人设和记忆),电话打给的却是机器人本人:同一个头像两种性格、两份记忆。所以拆开:新做聊天页,管理对话不动。

改了什么

后端(model/assistant/web_chat.go、webui/web_chat.go)

  • 通话和聊天页共用「主人私聊」:ownerChatEvent 造一条主人发来的私聊,replyAsOwner 走现有回复流程,回复在发送最后一步交给页面(deliverToWebChat),不发到平台。
  • GET /api/assistant/chat?profile=:能不能聊 + 最近 200 条私聊记录(平台私聊、聊天页、通话都在里面)。
  • POST /api/assistant/chat:发一句话,NDJSON 流式返回每条回复,15 秒心跳,done 结束或带错误。
  • 新的 event.webChat 统一跳过输入状态、Telegram 草稿流、合并转发、tts 工具和私聊准入;原来的 voiceCall 只管通话特有的口语化提示和保留句号。通话代码改用共用入口,行为不变。

前端

  • 侧栏「日常 → 聊天」(ChatView.vue):机器人列表带头像和最后一条消息,选中只淡淡衬底色;私聊气泡左右分开、带头像,五分钟以上插时间分隔,等回复时是打字气泡,副标题「对方正在输入…」,发送失败可点重发;右上角电话按钮。手机上先列表后聊天,返回键回列表。
  • VoiceCallScreen.vue:全屏通话界面(头像、时长、实时字幕、轻点打断、静音 / 对讲 / 打字 / 挂断)。对讲和静音在本地控制上行,通话中随时切换不用重连;AudioContext 和麦克风授权在点电话时就发起。挂断后聊天页刷新记录。
  • 删除顶栏电话入口、CallView.vue 和 /call 路由。
  • 顶栏的管理对话按钮改成开关:再点一下回到打开前的那页。
  • 演示模式补了聊天页的假数据。
  • docs/voice-call.md 加了聊天页和接口说明。

用户影响

  • 新增侧栏「聊天」。在这里和机器人说的话按主人私聊处理,会进她的记忆和私聊记录;回复只在页面上显示,不会发到 QQ / Telegram。
  • 登录 WebUI 的人就是主人,所有机器人都能聊天和通话:填了主人账号就和平台私聊是同一段记录;Telegram 主人填 @用户名时用记下的数字 ID,还没有就用用户名;没填主人时用 webui-owner 单独一段,同样按主人对待(只认服务端造的聊天事件,平台消息冒用不了)。
  • 和 QQ 一样她回复前也能连着发,多句可能被并成一条回复。
  • 回复里的本地文件、base64 图片在页面上不显示,只显示 http(s) 图片。
  • 语音通话入口从顶栏挪到聊天页;旧的 /call 地址不再存在。

验证

  • Go:go test -race(model/assistant、webui、model/voicecall、internal/safego)和 TZ=UTC go test ./... 全过;新增 web_chat_test.go,覆盖回复不发平台、不带通话提示、记录可读、没填主人 / Telegram 用户名 / QQ 官方 openid 都按主人对待且平台冒用不了、图片过滤、登录要求。
  • 前端:vue-tsc、单测 289 项(新增时间分隔、流式分帧)、生产构建、check-public-repo.sh 通过。
  • demo 模式目视:窄屏列表→聊天→返回、宽屏两栏、发消息出现转圈→打字气泡→回复、管理对话按钮开关。
  • 真实实例(本机独立测试实例,gpt-5.6-terra + 本机 Whisper + 谷歌翻译朗读):聊天页发「给我讲个笑话吧」约 10 秒收到回复;之前通话里说的那轮也出现在聊天记录里;连发两句被并成一条回复。通话链路沿用 feat(voice): 实时语音通话通道与网页测试页 #1211 的验证(feat(voice): 实时语音通话通道与网页测试页 #1211「实时语音通话通道」)。
  • 没在真实手机麦克风上试过(需要 HTTPS)。

@SuInk
SuInk force-pushed the claude/voice-call-admin-chat branch from 8c8a2ba to 60d1506 Compare October 27, 2026 16:23
@SuInk SuInk changed the title feat(webui): 管理对话改成聊天软件的样子,语音通话收进对话里 feat(webui): QQ 式聊天页,打字和语音通话都是和机器人本人私聊 Oct 27, 2026
SuInk added 4 commits October 28, 2026 01:00
管理对话原来是问答工具的排版,输入框下面挂着机器人和模型两个下拉框,语音通话又是顶栏里单独一页。用户希望它像真的聊天软件:对面是谁、在不在输入一眼能看到,打电话就在对话里点,选机器人和模型这类不常动的东西收进设置。

- 标题栏显示对面的头像和名字,处理中显示「正在输入…」;消息改成左右气泡,对面带头像,等待时是打字气泡。
- 输入栏改成一行:加号、胶囊输入框(随内容长高)、发送。机器人和模型选择挪到「⋯ → 聊天设置」。
- 标题栏加电话按钮,全屏通话界面照手机通话做:头像、时长、实时字幕,静音、对讲、打字、挂断。
- 对讲和静音在本地控制上行,通话中随时切换,不用重连;麦克风和 AudioContext 在点电话时就发起。
- 去掉顶栏的独立通话页入口和 /call 路由。
管理对话里的「管理助手」替主人干活,不带机器人的人设和记忆;电话打给的却是机器人本人。两者放在一个窗口里,同一个头像会有两种性格、两份记忆。所以拆开:新做一个聊天页,打字和打电话都走主人私聊,管理对话恢复原样。

- 后端:通话和聊天页共用「主人私聊」(web_chat.go):ownerChatEvent 造事件,replyAsOwner 走回复流程,回复在发送最后一步交给页面。新增 GET/POST /api/assistant/chat,读私聊记录、流式收回复。
- event.webChat 统一跳过输入状态、草稿流、合并转发、tts 工具和私聊准入;voiceCall 只管通话特有的口语提示和保留句号。
- 前端:侧栏「日常 → 聊天」,左边机器人列表(头像、最后一条消息),右边私聊气泡、时间分隔、打字气泡、失败重发,右上角电话按钮。手机上先列表后聊天。
- 管理对话恢复成 main 的样子;顶栏的管理对话按钮再点一下回到打开前的那页。
整行涂成主题色太扎眼,改成和微信、QQ 桌面版一样的浅灰底,文字颜色不变。
登录 WebUI 的人就是主人,不该因为机器人没填主人账号、或者 Telegram 主人填的是 @用户名就聊不了。另外聊天页原来要等她回完才能发下一句,和 QQ 不一样。

- 主人账号:填了就用它,和平台私聊是同一段记录;Telegram @用户名用记下的数字 ID,还没有就拿用户名当账号;没填主人时用 webui-owner,OwnerIDForEvent 只对服务端造的 webChat 事件把它认成主人,平台消息冒用不了。
- 聊天页每句单独发出,按机器人计数等回复中的句数,「正在输入…」和打字气泡跟着它;失败的句子随时能重发。
@SuInk
SuInk force-pushed the claude/voice-call-admin-chat branch from 8adda18 to 5cd4442 Compare October 27, 2026 17:02
@SuInk
SuInk merged commit 0653dab into main Oct 27, 2026
15 checks passed
@SuInk
SuInk deleted the claude/voice-call-admin-chat branch October 27, 2026 17:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant