qwen-code/packages/live-host
Xiong Wang f649d65d1f
feat(live): add visual input, proactive assistance and memory (#11369)
* feat(live): add visual input, proactive memory and desktop controls

* fix(live): preserve upstream checks and finalize migration validation

* feat(live): open active configuration from host settings

* fix(live): address lifecycle and proactive review findings

* feat(live): add subagent controls and diagnostics with review fixes

---------

Co-authored-by: 菲兹 <feizi.wx@alibaba-inc.com>
Co-authored-by: Shaojin Wen <shaojin.wensj@alibaba-inc.com>
2026-09-11 03:13:13 +00:00
..
build feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
resources fix(live): restore Live Host after desktop removal (#9994) 2026-08-25 12:32:31 +00:00
scripts feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
src feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
.gitignore fix(live): restore Live Host after desktop removal (#9994) 2026-08-25 12:32:31 +00:00
electron-builder.yml feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
package-lock.json feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
package.json feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
README.md feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
tsconfig.json feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00
vite.config.ts feat(live): add visual input, proactive assistance and memory (#11369) 2026-09-11 03:13:13 +00:00

Qwen Live Host

Qwen Live Host 是独立 Qwen Live daemon 和 WebShell Live Voice 在 macOS 上的原生组件。它承载小浮层、 Electron 全局快捷键、麦克风输入、可选摄像头输入、扬声器输出和内置原生 Appshot。Host 不打开 WebShell 或 Session 窗口;对话由连接的 daemon 管理,编码任务由配置的后端执行。没有浏览器 麦克风或浏览器快捷键降级方案。

用户要求

  • macOS 12 或更高版本。
  • 本机运行的独立 qwen-live daemon 或 Qwen Code WebShell。
  • 可调用 qwen3.5-omni-plus-realtime 的 DashScope API key。

WebShell 内置 Live Voice 默认关闭;独立 qwen-live 可直接从命令行启动并连接 Host。 原生音视频功能目前要求 macOS。

首次启用

  1. 在 WebShell 打开 设置 → 实验性功能 → Qwen Live
  2. 输入专用于 Realtime 模型的 DashScope API key快捷键默认是 Command+E,可在同一处修改。
  3. 打开开关并确认安装。WebShell 优先从阿里云 OSS 镜像下载当前架构的签名 Host 镜像不可用时回退到独立的 GitHub live-host-latest feed。下载后校验 manifest、 SHA-256、bundle identity、Developer ID 签名和 Gatekeeper然后原子安装到 /Applications/Qwen Live Host.app 并启动。
  4. 按 Host 引导完成麦克风以及当前视觉源需要的授权Screen 需要辅助功能和屏幕 录制Camera 需要摄像头。授权只能由用户在 macOS 完成;当前 Source 的 readiness 通过前 Live 不可使用。

API key 只写入用户级设置。WebShell 只能看到“已配置”状态,不会读取或回显 key。 关闭 Live 会停止当前通话、撤下快捷键和 Host discovery但不会卸载 Host 或删除 Live 对话。

开发构建

开发者需要 Node.js 22。在仓库根目录执行

cd packages/live-host
npm ci
npm run build
npm run typecheck
npm test
npm run dist:mac

构建产物位于 packages/live-host/dist/,打包产物位于 packages/live-host/release/。正式用户不需要手工下载 DMGWebShell 的实验性设置 负责安装和启动。

发布

Live Host 使用独立的 Qwen Live Host Release workflow、版本号和发布节奏 不参与也不阻塞 Qwen Code Desktop Release。PR 会自动执行一次未签名 dry run 检查 arm64/x64 的 DMG、ZIP 和 manifest正式发布只能从 main 手工触发,并执行 Developer ID 签名、notarization、Gatekeeper 和 stapler 验证。

版本发布使用 live-host-vX.Y.Z tag包含两个 DMG、两个 ZIP、 Qwen-Live-Host-manifest.jsonSHA256SUMS.txt。非 draft、非 prerelease 的 正式版本还会更新固定的 GitHub live-host-latest feed并在发布成功后调用一次 独立的 OSS 镜像 workflow。镜像保存版本化 ZIP 和 manifest再发布一个 latest manifest需要重传时可手工运行同一镜像 workflow。WebShell 自动安装优先读取 OSS 失败时使用 GitHub feed。

构建会把仓库内的 Objective-C++ Appshot 源码编译成一个 universal N-API 模块, 并随 Host 一起签名。模块在 Host 主进程内调用 macOS 截屏与 AX API没有额外 Appshot App、Appshot Helper、MCP、CLI、插件、守护进程或运行时下载。正式产物必须通过 Developer ID 签名、notarization/staple、codesign、Gatekeeper 和 stapler 校验。

Host 不会自行创建或强制启用 Login Item。需要开机启动时由用户在“系统设置 → 通用 → 登录项”中显式添加。

Live 启用后daemon 会在 ~/.qwen/live/daemon.json 发布权限为 0600 的稳定 locator。Host 只连接 loopback 地址并校验协议版本和 daemon nonce。record 可能包含 bearer token不要打印、复制或共享其内容。

Live 被禁用、discovery 不存在或 daemon 断开时Host 的全局快捷键、音频和 Appshot readiness 保持 dormant。只有 v9 daemon 完成 welcome 后这些服务才启动;断开时会立即 清理音频 context 并解注册快捷键。

活跃 Live Session 的视觉上下文只走 Session-local 的内置视觉通道。它不会修改、隐藏 或跳过普通 Qwen 工具及用户配置的 MCPScreen 捕获使用的 Appshot 本身也不依赖这些 能力。

快捷键

快捷键由 daemon 通过每个 LiveStatus.shortcut 下发,默认是 Command+E。Host 使用 Electron globalShortcut 注册普通 accelerator不请求 Input Monitoring 权限,也没有 裸修饰键 helper。WebShell 设置通过 daemon 请求 Host 先注册新 accelerator成功后才 解注册旧值并持久化;冲突或非法值会保留旧快捷键并返回设置错误。退出或断开 daemon 也会解注册当前 accelerator。

菜单栏中的“新对话”会显式创建新的无项目对话;开始、停止当前通话是独立动作。

悬浮球与设置

初始化框和悬浮球首次分别按当前可见尺寸放在启动屏幕右下角,保留 20px 边距。 拖动初始化框标题栏或小球可移动, 位置保存到 Host 用户数据目录中的 overlay-position.json,下次启动恢复;显示器移除后 会调整到可见区域。小球按动画、工具栏和字幕的紧凑区域限位,不再被初始化框的透明空白 挡住。打开 Settings 或预览时会临时调整到完整可见的位置,关闭后恢复记忆位置;临时调整 不会覆盖拖动记录。状态刷新不会重新定位窗口。

鼠标移到小球上显示麦克风、播报、Start callEnd callSettingsQuit Host 按钮;移出后等待 1 秒淡出,移回或键盘聚焦会保持可用。工具栏位于球上方,为底部贴边 留出空间。Command+E 启动/结束通话。 Host 启动后会等待连接、当前来源权限和自检就绪,再自动开始一次交互;已有通话时不会 重复启动。手动启停/新对话/退出、自动启动失败、重连或 renderer 重载均不会再次触发 自动启动。重新启动 Host 才产生下一次自动启动意图。 结束后小球变灰并留在原位,不再自动隐藏。小球动画、摄像头预览和设置控件保持挂载, 状态/字幕变化不会重建它们;小球没有投影。半透明状态条位于小球下方,控制按钮悬浮在 上方;圆形齿轮按钮打开 Settings面板默认显示滚动条及轨道。 麦克风关闭或扬声器静音时,状态条第二行显示 Mic offSpeaker muted(支持中文), 同时保留第一行的通话状态或授权入口。麦克风静音会释放输入设备,取消静音后重新收音。

初始化页只处理连接、Source 和对应权限,不要求 Camera 用户先授权 Screen。 日常设置集中在 SettingsAudio Source麦克风、Video SourceScreenCamera、 Capture ModeOn DemandLive Feed三个同级设置组以及独立 daemon 支持的 Memory。 模式说明随已确认的选项更新。设置支持 Esc、外部点击关闭编辑草稿保留。 顶部的 Open config.json ↗打开 config.json ↗ 会使用系统为 JSON 文件关联的 默认 IDE文本编辑器打开当前独立 daemon 实际使用的配置(默认 ~/.qwen-live/config.json,也支持 daemon 的 QWEN_LIVE_DATA_DIR)。保存后需重启 Qwen Live 才应用手动修改。旧 daemon 或内置 qwen serve 不提供此入口能力;文件 缺失、不是常规文件(包括符号链接)或编辑器打开失败时会提示,不自动创建或覆盖配置。 设置标题栏可以拖动,与小球共享位置记忆;打开时先等待原生窗口完成屏内定位再显示, 避免边缘处先露出被裁切的面板。用户说话的小音量视觉响应已增强,保留有界动画和缓慢 回落,不会提高发送给模型的音频音量。

Settings 倒数第二组为 Language语言(其后是 Theme支持 简体中文English。 独立 daemon 确认后立即切换,并保存到 ~/.qwen-live/config.json 顶层 language zh-CNen);旧配置未设置时保持英文。通话中也可修改,不重连媒体、不丢编辑草稿。 旧 WebShell 连接仅保存 Host 本地语言偏好,不写独立 Live 的配置。首次未连接时使用 本地缓存,连接 standalone 后以 daemon 设置为准。语言不影响模型提示词/回答或用户 自定义名称。qwen-live init 的第一项也可通过左右方向键选择语言,后续问题随之切换。

全部固定 Live 展示文案统一维护在 packages/qwen-live/src/i18n/messages.ts 每个键并列 enzh-CN。修改后分别重建 Live 和 Host。Host 的构建别名直接编译 同一份纯文本模块,打包后不需要 qwen-live 运行时依赖;开发构建仍应在完整仓库内进行。 默认是 Screen + On Demand配置决定每次 daemon 启动的初值SourceMode 切换只影响 当前运行实例。

子智能体状态

悬停或用键盘聚焦小球时,侧面显示明确标注 Subagents子智能体 的摘要: 紧凑图标计数显示进行中和已完成;有运行任务时小点柔和闪烁(遵循系统减少动态效果设置), 需要用户输入时才显示提醒标记。悬停提示与辅助功能标签保留完整计数。 点击展开列表,再点击任务在同一个无边框悬浮面板中显示详情,查看原始委托、 实际运行状态、最新活动、公开中间文本、可用的计划/工具更新及最终结果。 Back返回 回到列表;列表与详情的标题区均可拖动,返回时保留位置并限制在屏幕内。 不再打开带 macOS 标题栏的独立详情窗口;关闭面板不会取消任务。

摘要离开后约 1 秒收起,鼠标移到摘要上会保持;点击展开后一直保留,直到点击关闭或 Esc。 拖动小球时只隐藏未展开的摘要,下次悬停按新位置贴靠。展开的列表/详情不会因失焦、 打开 Settings、拖动小球或连接中断而消失。任务面板不会挤压、移动或调整小球大小 状态更新不翻边、不重排已打开列表的点击目标,也不会把用户正在看的输出滚到底部。 自动展开的位置会避开小球、工具栏、预览和下方状态条的完整可见区域;原侧面不足以容纳 展开面板时选择有空间的另一侧,不把面板夹回状态条上。

进行中包含排队/等待输入任务;已完成包含成功任务及已取消的 Proactive monitor。 monitor 详情仍显示已取消,不伪装成成功;取消的 timerharness、失败和中断仍独立计数。 需关注只表示正在等待用户输入/授权,不包括失败或中断。持续 monitor 的每轮判断或通知不会增加子智能体数量, 通知排队/送达与任务结束是两个状态。追加到既有后台任务的指令不重复计数。

结束语音后 Proactive 停止采样并保留结束记录,后台 harness 任务继续运行及更新。 无通话时收到权限请求只登记等待,不新增自动批准;可在任务详情中按后端实际提供的 范围允许或拒绝,未确认所属任务的请求单独显示。普通文件系统拒绝不会被虚构成授权请求。 未关联请求也会点亮摘要的待处理标记。描述过长时请到后端完整查看后授权,仍可在这里拒绝。 Live 为支持的 Codex ACP 新会话选择明确提供的 Ask for approval 模式;不改全局权限、 不关闭沙箱,模式不支持或设置失败时记录警告。

列表和详情提供 Stop停止,只停止对应任务;后端尚未确认时显示正在停止,不会提前 宣称已结束,也不会用旧任务 ID 取消同一会话的新任务。停止请求与最终结果以静默文字 反馈给主 Omni前台忙时排队挂断后保留到本次 daemon 的下一次通话。Close 仅关闭面板。 Live 不再限制活动 Harnessmonitor 数量;独立并行的 Harness 任务使用独立会话, 同一会话保留追加/排队语义,后端自身的队列、配额以及机器和 API 资源限制仍适用。

任务历史只保留本次 daemon 运行;全部活动任务保留有限详情,已结束任务仅保留最近 32 条。 使用上一页/下一页访问任务,每页最多 32 条,单个快照上限 240 KiB超限时明确提示 省略/截断,总计数仍覆盖省略任务。此功能通过可选能力协商,仅在 支持的独立 Live daemon 连接上显示,不影响旧版 Host 或 WebShell。

Settings 最后一个选项 Theme主题 位于 Language 后,支持跟随系统(默认)、浅色和深色。 主题保存在 Host 本地,与 daemon 的模型Memory 配置无关;小球控件、设置和子智能体面板 同时更新,切换不会重建媒体或中断通话。

Quit Host 请求当前独立 Live daemon 完成通话、后端、Memory 和 discovery 清理后退出 Host不会关闭另外运行的 qwen serve。旧 WebShell 连接只结束 Live 并退出 Host。 从未连接到已认证实例时只退出 Host同一独立实例重连期间仍请求原实例退出。 退出未获确认时保留界面并显示错误、保持媒体停止,再次点击只重试原实例, 不会悄悄切到另一个 daemon。正常结束通话不会执行这条完整退出路径。 只有匹配的退出回执,或系统明确确认原 daemon PID 已不存在,才允许完成退出; 404、连接重置或拒绝连接都不单独视为退出成功。 清理失败时 daemon 保留同实例的退出控制入口和 discovery但拒绝新通话及普通请求 重试只处理尚未成功关闭的资源,全部完成后才确认退出。

连接独立 Qwen Live daemon 时Settings 的 Memory 区域提供记忆开关、 独立的 Visual memory 开关、选择记忆库、NewRename,以及 Consolidation model 设置(默认 qwen3.7-plus)。通话中可以开关和改名; 选择/新建记忆库和修改模型需要先结束通话。操作由 daemon 确认并写回 Live 配置, 内联编辑草稿不会被音频状态刷新打断。库默认存储在 ~/.qwen-live/memories。 daemon 断开时 Settings 关闭,未保存的编辑草稿保留到重新连接后再次打开。 qwen-live init 也会询问是否启用 Memory 和整理模型名,详细参数见 Memory 文档。旧的 WebShell 内置 Live 没有声明 Memory 能力时Host 不显示这一入口。

Camera 被选中后,气泡球上方默认显示镜像的本地预览小窗;没有字幕时更靠近小球。 球旁的小眼睛按钮可以隐藏/显示预览,独立于悬停工具栏。隐藏只影响本地小窗,不会停止 Camera 输入、视频帧上传或后台监控;切回 Screen 或 Quit 才关闭摄像头。再次选择 Camera 默认重新显示预览。空闲时画面只留在本机; Live Feed 在通话中按配置 FPS默认 1持续发送有界 JPEG。On Demand 的前台模型 通过 appshot 获取单次截图;若存在视觉 Proactive 任务,后台 Monitor 仍会按自己的 FPS 持续采样。任务等待播报时继续观察,新事件进入 FIFO结束通话会停止全部监控。

visualInput.cameraResolution 控制预览Live Feed 采集,默认 1280×720。 visualInput.cameraSnapshotResolution 独立控制 Camera Appshot默认 native 也可设置 { "width": 1920, "height": 1080 };环境变量为 QWEN_LIVE_CAMERA_SNAPSHOT_RESOLUTION=nativeWIDTHxHEIGHT。Host 优先从同一 camera track 拍摄静态照片;设备不支持时尝试临时调整视频采集约束,等新尺寸画面就绪后 截图并恢复预览。无法满足原生采集时明确报错,不会把预览的 720p 冒充原生照片。 Camera 高分辨率 JPEG 单独保存为 handoff asset上限 8 MiB不通过 Host WebSocket 传输;后台 Monitor 不调用这条高分辨率拍照路径。snapshotResolution 继续用于 Screen。

Screen Live Feed 与视觉 Proactive monitor 使用独立的完整显示器采集路径,包含桌面、 菜单栏、Dock 和其他应用,但排除 Live Host 自身窗口。Settings 的 Video Source 下可选 Display显示器,选择保存到 config.jsonvisualInput.screenDisplayId。 默认 primary 跟随系统主显示器,也可保存某块显示器的 UUID明确选择的显示器断开后 报错,不自动换屏。切换显示器会丢弃过期截图并清空 monitor 旧视觉缓冲。无需重新 init。 两条持续画面路径都使用 liveResolution,默认等比放进 1280×720完整范围不代表原生像素。 所有送入 Omni 的 JPEG 和 Host 传输预览受 1080p190 KiB 上限约束, Camera 原图 asset 与 Screen 的 PNG asset 不受该小图上限影响。 前台 Appshot 工具与 On Demand 视觉记忆仍使用原来的前台窗口截图不读取整屏Camera 不变。

停止通话、切换 Source/Mode、daemon 断开或 Host 退出都会清理不再使用的通话采集。 停止通话后Camera Source 的可见小窗可以继续显示本地预览,此时不会上传画面; 切回 Screen、断开 daemon 或退出 Host 会关闭摄像头。 Camera Source 需要摄像头权限Screen On Demand 的 Appshot 需要辅助功能和屏幕录制权限, Screen Live Feed 仅需屏幕录制权限。未选中的 来源权限不会阻止 Live。通话中切换到尚未授权的来源时Host 会先保留当前可用来源, 授权成功后再一次性完成切换;授权取消或失败不会让正在工作的来源提前失效。

开发诊断可在终端启动开发版或应用可执行文件并传入 --live-debug。不要给 Electron Host 传 --debug,该参数会被 Electron 当成已废弃的 Node 调试参数并在启动前退出。 日志只包含状态、readiness blocker、尺寸、字节数 和错误码不包含图片、音频、API key 或转写内容:

cd packages/live-host
npm start -- --live-debug

"release/mac-arm64/Qwen Live Host.app/Contents/MacOS/Qwen Live Host" --live-debug

Proactive 判断、通知排队播报、harness 任务和 Realtime 生命周期日志由 daemon 输出, 需在另一个终端运行 qwen-live --debug。Host 的 --live-debug 不会替代 daemon 的日志开关。

排查 monitor 输入时,用 frameHashJPEG 字节的 SHA256 前 16 位)对应 Host 的 visual_snapshot_capturedvisual_frame_sent、daemon 的截图/帧记录,以及 proactive.monitor_image_sent。后者只表示实际写入模型连接的帧,不把排队当作已发送。 proactive.monitor_commit 显示本次实际发送的图片数、音频字节数和时长(含协议要求的静音), monitor_committed 表示服务端确认提交,monitor_action 区分 waitreplyfunction_callinvalid。 这些日志不包含图像、音频或模型输出原文。

daemon 的 debug 模式另外为视觉 Monitor 保存真实请求,目录为系统临时目录下的 qwen-live-monitor-debug/。每个 Monitor 一个目录,每次推理保存 request.json、 实际送出的 JPEG、含协议静音的 16 kHz input.wav,以及结果 response.jsonproactive.monitor_debug_startedproactive.monitor_request_saved 日志给出绝对路径。 仅 daemon debug 开启Host 的 --live-debug 单独启用不会录制,纯音频 Monitor 也不录制。 启动及新建 Monitor 时清理,只保留最近创建的 10 个 Monitor不是最近 10 次请求)。 被清理的 Monitor 继续运行但停止录制;文件仅当前用户可访问。内容包含真实屏幕/摄像头、 任务文本和混合 Monitor 的麦克风输入,虽然不保存连接凭据,画面或音频中的秘密不会被脱敏。 录制失败会单独报错而不影响通话;长时间 debug 可能占用较多磁盘,诊断完请关闭 debug。 完整格式与清理规则见 Qwen Live README

native_display_changed 记录原生显示器事件与几何信息;overlay_position 记录 Host 主动 定位的原因及前后坐标,overlay_native_moved 记录原生窗口移动。非几何显示器事件不会再 丢弃正在采集的帧或中断拖拽;真正需要边界修正时才调整小球位置。

内置 Appshot 与来源相关授权

权限 授权主体 用途
麦克风 Qwen Live Host 采集 Live 对话音频
摄像头 Qwen Live Host Camera Source 的预览、实时帧或单帧截图
辅助功能 Qwen Live Host 读取前台窗口的可访问性树
屏幕录制 Qwen Live Host Screen Source 的实时帧或单帧截图

Appshot 是 Host 的内部核心能力。内置原生模块选择最前面的非 Host 普通窗口,通过 macOS 原生 API 返回应用信息、窗口标题、AX 文本和 PNG。模型侧的 appshot 是无参数、 只读工具,捕获气泡球当前选中的 Source不能通过工具参数临时指定另一个来源、窗口、 坐标或动作。Live Feed 模式禁用该工具On Demand 模式才允许调用。

Host 激活后会在 Screen 为当前或待切换来源时定期刷新 Appshot 权限,以便授权完成后 自动恢复或切换;每次真实 Screen 捕获还会在 Host 进程内重新验证两项权限。当前来源的 授权丢失会令捕获失败并使 Live fail closed。整个流程不启动或探测任何外置屏幕工具。

音频和 fail-closed

Omni 响应以单声道 16-bit、24 kHz PCM 接收。播放 AudioContext 不指定采样率,使用当前 系统输出设备的默认时钟(如 44.14896 kHz不强制更改设备采样率。 当前协商了输出结束标记的连接,对每条响应进行连续、带抗混叠滤波的流式重采样,再放入 设备采样率的 AudioBuffer按整数采样点连续排程避免逐块转换的衔接尖峰及无谓间隙。 结束标记到达时输出短暂的滤波尾部。未协商结束标记的旧连接保持原有 Web Audio 逐帧转换和播放排空逻辑,不会等待不存在的标记。 --live-debug 日志中的 output_context_ready 显示源/输出上下文采样率及是否重采样。

蓝牙耳机的麦克风被打开时macOS 可能将耳机切换到免提通话模式,影响同时播放的音乐/视频; 这与模型 PCM 采样率是两回事。可在 Audio Source 选择 Mac 内置麦克风,输出仍使用蓝牙耳机。 关闭麦克风时 Host 立即停止输入 track 并释放捕获上下文,而不只是丢弃录音数据; 静音期间设备变化不会重新打开麦克风,取消静音后才重新收音。

devicechange 会在收音时检查/替换输入,在空闲时重新自检;静音通话不重新获取输入。 输入 track ended、播放失败或音频帧无法交给 daemon 时Host 会先 将 input/output 标记为 unavailable、停止当前通话并清理旧 context再重新执行自检。 麦克风重新授权后只有实际输入自检通过才会恢复 ready。overlay renderer、preload 加载、 页面加载失败或 renderer 无响应也会执行 fail-closed。

任一权限、自检、快捷键或 provider 配置失败时Live 都保持不可用。Host readiness 不会连接 Realtime首次就绪自动开始或用户手动开始对话时才建立 provider WebSocket。限流或配额错误不做 自动重试或后台探测,用户稍后可手工重试。

卸载

  1. 从菜单栏选择“退出 Qwen Live Host”。
  2. 如果用户曾手工添加 Login Item在系统设置中将其移除。
  3. /Applications 删除 Qwen Live Host.app
  4. 在 WebShell 的 设置 → 实验性功能 → Qwen Live 中关闭功能。
  5. 如不再需要,可在“隐私与安全性”中撤销 Host 的麦克风、摄像头、辅助功能和屏幕录制权限。