Skip to content

Releases: nancheung/open-xiaozhi-client

v0.1.5

09 Jun 13:55

Choose a tag to compare

本版本进行了核心架构重构,使代码更稳定可靠,同时添加启动参数支持和改进版本检查。

✨ 新增功能

  • 启动参数支持:支持通过命令行指定 OTA 地址和端口

    open-xiaozhi-client-webui --ota http://server/ota --port 8080
  • 外部访问:监听地址改为 0.0.0.0,支持外部访问。注意:必须要https

  • 实时版本检查:从 npm 注册表获取最新版本

🔧 架构改进

  • 分层设计:将业务逻辑、适配器、UI 分离,降低耦合
  • 状态机:用显式的状态机管理连接和对话流程
  • 事件驱动:UI 通过命令分发而非直接调用
  • 纯函数核心:业务逻辑零依赖,便于测试

🧪 质量提升

  • 新增 200+ 单元测试,覆盖核心逻辑
  • 所有测试通过(143 项)
  • 生产构建验证通过

v0.1.4

06 Jun 02:25

Choose a tag to compare

本版本新增实时耗时分析面板,修复关键的录音异步竞态问题,进一步提升交互体验和调试能力。

✨ 新增功能

实时耗时分析面板

  • 完整的时延可视化

    • 在协议日志标签页下方新增专用的耗时分析面板
    • 可视化每轮语音交互的关键时间点:
      • 用户开始说话
      • 用户说完话(STT 完成)
      • 服务器进入说话状态(TTS 开始)
      • 服务器停止说话(对话完成)
  • 关键性能指标

    • 端到端延迟:用户开始说话到服务器开始回复的总耗时
    • 感知延迟(重点):用户说完话到服务器开始说话的等待时间
    • 毫秒级精度,实时更新
  • 便于诊断

    • 快速识别系统中的性能瓶颈
    • 对比不同模式下的交互延迟
    • 服务端性能基准对标

🐛 Bug 修复

修复关键的录音异步竞态问题

背景:聆听状态下服务器主动关闭连接后,麦克风仍持续采集、日志持续出现 ↑ BIN 二进制数据

根因分析

  • startRecording() 是异步函数,包含多个 await 点(getUserMediaaddModule
  • 连接关闭时 teardown() 调用 resetAudio()audioStatus 置为 idle
  • 此时 startRecording 中的 await 仍在进行中,refs 尚未赋值
  • stopRecording() 发现 refs 为空,无可清理直接返回
  • 当 await 完成后,startRecording 继续执行,将 MediaStream 和 AudioWorklet 接好并启动
  • 结果:audioStatus 已为 idle 但仍在持续录音,worklet 不停地写 ↑ BIN 日志

解决方案:引入录音会话代号(epoch)机制

  • startRecording() 领取会话号,在每个 await 后校验会话是否仍有效
  • 若会话失效(epoch 已更新),则立即释放刚获取的麦克风轨道 / AudioContext 并退出,绝不接线 worklet
  • stopRecording() 递增会话号,使任一进行中的启动作废
  • 保证了 worklet 启动的原子性和正确性

📊 性能与诊断

  • 实时可见的系统端到端延迟,便于服务端性能对标
  • 精细化的时间点记录,有助于识别语音处理链路中的瓶颈
  • 支持多轮交互累积数据,便于性能趋势分析

🧪 质量保证

  • 新增 LatencyChartLatencyPanel 单元测试
  • 新增 latencySlice 单元测试(时间点记录、时差计算)
  • 新增 useAudio 竞态回归测试(确保 epoch 机制正确)
  • 所有 TypeScript 编译通过,无类型错误

v0.1.3

31 May 08:40

Choose a tag to compare

v0.1.3

本版本新增摄像头拍照功能,完善 OTA 连接和设备激活流程,并增强协议交互能力。

✨ 新增功能

摄像头拍照能力 (self.camera.take_photo MCP 工具)

  • 完整的视觉交互链路:WebUI 调用摄像头采集 → JPEG 抓拍 → POST 到视觉端点 → 服务端返回分析结果
  • 摄像头采集模块 (src/features/camera/cameraCapture.ts)
    • 基于 getUserMedia 实时采集视频流
    • Canvas 2D 绘制和 JPEG 压缩抓拍
    • 自动清理和资源释放
  • 摄像头管理状态切片 (src/features/camera/cameraSlice.ts)
    • 摄像头启用/禁用状态
    • 拍照进度和错误处理
  • MCP 工具实现
    • 解析服务端初始化时下发的 capabilities.vision.{url, token}
    • 工具签名:self.camera.take_photo(question: str) → analysis_result
    • 抓拍后以 multipart/form-data 格式发送:question + JPEG 图片
    • 异步等待服务端视觉分析结果
  • 摄像头实时预览面板(设备 Tab)
    • 实时视频预览
    • 拍照按钮和状态提示
    • 连接断开时自动释放摄像头
  • 完整的单元测试覆盖
    • src/features/mcp/__tests__/tools.test.ts - 拍照工具测试
    • src/ws/__tests__/wsManager.test.ts - 摄像头初始化和清理测试

OTA 连接完善

  • 系统信息补齐 (src/features/connection/systemInfo.ts)
    • OTA 请求头:Activation-Version, User-Agent, Accept-Language
    • OTA 请求体:version、language、mac_address、uuid、chip_model_name、application、board
    • 提供更完整的设备身份信息,便于服务端识别和配置下发
  • 设备激活轮询流程 (src/features/activation/activate.ts)
    • 自动检测激活消息中的 challenge 字段
    • 触发 POST /activate 轮询流程
    • 按 HTTP 200(激活完成)或 202(继续轮询)响应码处理
    • 激活完成后自动继续建立 WebSocket 连接

abort 交互增强

  • buildAbort() 现支持可选的 reason 参数
  • 支持传递 "wake_word_detected" 等原因码,便于服务端记录中断原因

🧪 质量保证

  • 所有新功能覆盖单元测试
  • TypeScript 严格模式下 tsc -b 编译通过
  • 摄像头资源泄漏防护:WebSocket 断线时自动释放

📦 依赖

无新增依赖。

统计

  • 3 个 commits
  • 11 个文件修改/新增
  • ~550+ 行代码变更

兼容性

  • 需要支持 getUserMedia 和 Canvas 2D 的浏览器
  • 服务端需支持 capabilities.vision 下发和 /activate 轮询端点

v0.1.2

27 May 17:03

Choose a tag to compare

本次版本聚焦于 WebUI 交互体验升级、音频模式完善、设备控制统一化,同时补齐了多项稳定性修复与发布准备工作。整体上,客户端在 响应式布局、实时语音交互、设备设置管理 方面都有明显提升。

✨ 新增特性

1. 完整实现三种音频监听模式

  • 完善 Auto / Manual / Realtime 三种监听模式的行为逻辑。
  • Auto 模式 下,TTS 播放结束后可自动恢复监听,更贴近半双工语音助手体验。
  • Realtime 模式 下支持播放 TTS 时持续录音,实现更自然的全双工对话。
  • 在 TTS 过程中,用户可以更直接地打断并开始新一轮语音输入。

2. 全新响应式 ClientView 布局

  • 重新设计主界面,支持 窄屏/宽屏自适应布局
  • 窄屏下采用更紧凑的状态条、对话区与底部控制栏布局。
  • 宽屏下升级为 双栏布局:左侧对话历史,右侧命令中心,信息层次更清晰,调试和交互效率更高。

3. 新增统一设备设置面板

  • 使用新的 DeviceSettingsPanel 替代原有 IoT 面板。
  • 集成 音量、亮度、主题 等设备设置。
  • 抽离统一的设备设置入口,方便 UI 与 MCP 工具共用同一套控制逻辑。

4. 设备设置与面板布局持久化

  • 设备的 音量 / 亮度 / 主题 现在支持本地持久化。
  • 调试面板布局比例也会自动保存,下次打开可恢复之前的使用习惯。

5. 音频可视化体验增强

  • 音量条和波形图支持 响应式尺寸适配
  • Canvas 分辨率会随容器尺寸同步更新,提升不同屏幕下的显示质量和清晰度。

⚡ 优化改进

  • 优化窄屏布局下的交互细节,提升输入反馈和音频状态展示的一致性。
  • 活跃音频状态下,将模式切换图标替换为更直接的 中断/Abort 按钮,减少误操作成本。
  • 优化窄屏与宽屏场景下的 STT/TTS 展示逻辑,更清楚地反映“用户在说”和“服务端在回应”的并行状态。
  • 协议日志时间戳精确到 毫秒,便于排查时序问题。
  • 日志中的播放按钮改为内联显示,界面更紧凑。
  • README、截图、功能说明、开发指引与路线图同步更新,补充 License 和 npm 发布信息。

🐛 Bug 修复

  • 修复 Realtime 模式 下上下行音频流在协议日志中无法独立正确合并的问题。
  • 修复连接关闭后录音未在所有路径下正确停止的问题,避免麦克风与 AudioContext 残留占用。
  • 修复 Realtime 模式下停止麦克风时发送错误控制指令的问题,改为正确发送 abort
  • 修复部分音频状态切换场景下自动恢复监听行为不准确的问题,减少异常重启或错误中断。

📦 其他

  • 版本更新至 v0.1.2
  • 补充项目 License
  • 更新发布配套文档与展示素材

v0.1.1

23 May 19:54

Choose a tag to compare

更新内容

新功能

  • 新增 Conversation History 气泡式对话历史区域,并将其挂载到 STT / TTS 区域下方,方便查看完整对话过程。
  • 引入独立的对话状态管理,并将其接入 WebSocket 与音频链路,使聊天记录展示更稳定、上下文更清晰。
  • 优化协议日志展示方式:连续的二进制 Opus 音频帧会自动合并显示,减少日志刷屏,并支持在消息日志中直接回放音频。
  • 将原有的虚构 MCP mock 工具替换为基于真实浏览器能力的实现,包括音量控制、主题切换、亮度调节、设备状态获取、系统信息获取、页面重启以及固件升级链接打开等能力。
  • 将固定宽度面板升级为 react-resizable-panels,支持更灵活的界面布局调整。
  • 服务地址输入改为直接填写完整 OTA URL,减少连接配置歧义。
  • 应用版本号改为动态注入,确保界面显示、运行时信息与发布版本保持一致。
  • 增加版本更新检测相关能力,为后续发布与升级流程提供支持。

修复与优化

  • 修复了 react-resizable-panels v4 的 API 适配问题,确保布局组件按预期工作。
  • 修正了对话历史面板尺寸配置以及助手消息文本来源问题,避免左侧面板异常变窄,并提升历史记录展示准确性。
  • 优化助手消息在 tts-start 相关生命周期中的处理逻辑,提升播放过程中回复气泡的稳定性。
  • 抽离并复用 useAudioPlayback 播放逻辑,同时调整消息日志中的播放按钮交互与文案,提升音频回放体验。

发布与工程化

  • 新增 npm 发布工作流,完善发布自动化流程。
  • 项目版本更新至 0.1.1
  • 补充本地 worktree 忽略规则,减少本地开发环境对版本控制的干扰。

完整更新

Compare: v0.1.0...221998c

v0.1.0

23 May 16:21

Choose a tag to compare

v0.1.0

基于 Web 技术实现的小智 AI 客户端,通过 WebSocket 协议与小智设备通信,支持实时语音对话。

功能

实时语音通话

  • 基于 AudioWorklet 实现低延迟麦克风录音与扬声器播放
  • 使用 Opus 编解码器(opusscript / WebAssembly)对音频流进行实时编解码
  • 录音侧实时音量条(VolumeBar)、AI 回复侧波形动画(WaveformBars)可视化反馈
  • 支持麦克风多种监听模式切换

WebSocket 连接管理

  • 完整实现小智 WebSocket 协议,覆盖 hello / listen / tts / mcp / iot 消息类型
  • 连接状态机:未连接 → 连接中 → 已激活 → 通话中
  • 设备 ID 自动生成,支持手动配置;连接配置与界面设置持久化至 localStorage

协议调试面板

  • 实时展示所有 WebSocket 消息,方向着色区分收发
  • 自定义 JSON 发送面板(Ctrl+Enter 快捷发送)
  • IoT 指令描述符编辑器与接收指令列表
  • HTTP 面板支持 update_config / restart 服务端操作
  • 设置面板可调整 hello 握手参数、音频配置、连接超时

npm 发布

  • 包名 open-xiaozhi-client-webui,支持 npx 一键启动

技术栈

Vite · React · TypeScript · shadcn/ui · Tailwind CSS · Zustand · AudioWorklet · opusscript (WebAssembly)