Skip to content

feat: Add frontend observability probes#12

Merged
lanyue-llk merged 26 commits into
lex-mainfrom
observability
Jul 1, 2026
Merged

feat: Add frontend observability probes#12
lanyue-llk merged 26 commits into
lex-mainfrom
observability

Conversation

@jiejuncai-ly

Copy link
Copy Markdown

变更概述

这个 PR 在前端加入可开关的观测事件采集,把浏览器端的输入音频、远端播放音频、房间连接和后端输出 marker 统一成前端可发布的数据包,供 LexVoice 后端按同一 session/room 维度关联分析。

主要改动

1. 前端观测协议与音频活动检测

  • 新增 lib/observability.ts,定义前端观测事件、LiveKit data packet 发布和后端 marker 解析。
  • 新增 lib/frontend-audio-observer.ts,检测音频活动起止、尾帧和媒体轨道播放状态。

2. LiveKit 会话链路接入

  • hooks/useBrowserSourceClient.tshooks/useRoom.tscomponents/app/app.tsx 中发布浏览器输入、房间连接和远端播放观测事件。
  • 新增 components/livekit/remote-audio-playback-observer.tsx,观察 agent 远端音频播放情况。

3. 前端边界与测试覆盖

  • 增加聊天空转写过滤、视频预览选择 helper 和配置项校验,避免观测噪声影响用户界面。
  • 为 observability、audio observer、chat filter、video preview selection 和项目配置补充测试。

影响说明

  • 默认行为受 OBSERVABILITY_ENABLED 控制;关闭时不会发布前端观测事件。
  • 开启后后端可以关联浏览器输入、agent 输出和播放链路,便于定位无声、空转写和媒体轨道异常。
  • 用户可见 UI 变化集中在状态过滤和预览选择稳定性上,风险主要在前端 LiveKit session/audio observer 集成路径。

Verification

  • pnpm test

    ✅ passed: 92 tests passed

  • pnpm lint

    ✅ passed: eslint completed with exit 0

  • git diff --check origin/lex-main..HEAD

    ✅ passed: no output

@jiejuncai-ly jiejuncai-ly marked this pull request as ready for review June 24, 2026 06:16
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@jiejuncai-ly

Copy link
Copy Markdown
Author

关于最新 review 里剩下的 3 个 P2,本轮暂不继续修改,理由如下:

  1. audioContext.resume() 失败只 console.warn:这是一个可观测性增强项,不是当前主链路 bug。frontend-audio-observer 同时服务输入/输出音频活动检测,直接在这里发 BROWSER_AUDIO_VAD_PROBE_UNAVAILABLE 容易把“AudioContext resume 失败”和“VAD 探针不可用”混成同一个语义;如果要做,应该先补一个明确的 probe-unavailable 事件/回调设计,再让调用方决定怎么上报。为了避免本 PR 继续扩大行为面,先保留当前 warn。

  2. backend marker name 缺少长度上限:这个建议属于 defensive hardening,而且 review 里“超长 name 会写入 outputSegmentsRef”的判断不准确。当前 onDataReceived 解析 marker 后只通过 outputSegmentAttributesFromMarker() 提取固定的 segment 属性写入 outputSegmentsRef,不会把 name 存进去。这个可以后续补长度上限,但不影响当前 observer 归属和 VAD 时间点修复。

  3. sanitizeObservabilityAttributes 未过滤数组:同样是 malformed/malicious packet 的防御项。当前后端 marker 协议发送的是 object,前端最终也只提取固定的 output segment keys;数组下标不会进入最终的 outputSegmentsRef segment 属性。可以后续做输入硬化,但本轮不继续为非阻塞 P2 增加改动面。

本 PR 这轮已经修掉两个 P1,并且 test / claude checks 都已通过。为避免继续 churn,我建议这些 P2 留作后续 hardening 小 PR。

lanyue-llk

This comment was marked as resolved.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@lanyue-llk lanyue-llk left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review 结论:建议先修再合。整体 observability 协议、浏览器输入 VAD、真实 <audio> 播放链路接入、开关门控和清理路径这轮看下来基本是成立的;但 session/stop 新增的 room-input stop 逻辑把非当前输入源的服务也带上了,会造成跨设备副作用。

  1. [P1] app/api/session/stop/route.ts:175-198resolveRoomInputStopUrls() 只根据 INPUT_SOURCE 判断要 stop 哪些 room-input URL,导致两个不兼容仓库现有配置语义的行为:
  • INPUT_SOURCE=primebot 时会 POST PRIMEBOT_INPUT_PARTICIPANT_URL/stop,但 app-config.tsSERVER_ROOM_INPUT_DEVICES 只有 xunfei/generic,现有测试也明确写了 “frontend keeps primebot on the non-server room input path”。这个 PR 等于给 primebot 增加了新的 room-input stop 副作用。
  • INPUT_SOURCE=mixed 时会把 xunfei/generic/primebot 三类 URL 全部加入候选。实测在 ROOM_AUDIO_INPUT_DEVICE=xunfeiROOM_VISION_INPUT_DEVICE=browserROOM_OUTPUT_DEVICE=browser 且三个 URL env 都存在时,stop route 会同时 POST http://xunfei.local/stophttp://generic.local/stophttp://primebot.local/stop。这会停止本 session 根本没选用的 generic/primebot 服务。

这属于和本 PR 主题相邻但不应扩散的 lifecycle 改动:浏览器 observability 不应该让 primebot 或未选中的 mixed role 服务被额外 stop。建议这里复用/对齐 resolveInputDeviceConfig 的语义,只对实际选中的 audio/vision role 且属于 server room input 的设备生成 stop URL;primebot 除非产品语义明确改成 server room input,否则不要纳入 room_input stop。请同时补测试覆盖 INPUT_SOURCE=primebot 不调用 PRIMEBOT_INPUT_PARTICIPANT_URL,以及 mixed 只 stop 当前选中的 server role URL。

验证:已同步最新 PR head 3df5f8655c560585454986edd0142dbeb87b44b5。本地直接运行 ./node_modules/.bin/tsx --test tests/*.test.mjs 通过(101 passed)、./node_modules/.bin/eslint . 通过、./node_modules/.bin/tsc --noEmit --pretty false 通过、./node_modules/.bin/next build 通过(仍有 onnxruntime-web 的静态分析 warning,当前不阻塞)。Codex runtime 下的 pnpm test/lint 会先触发 pnpm 11 的 ignored-builds 策略,未进入脚本本体,所以使用了 direct bin 验证。

其余逐文件看下来,chat 空转写过滤、video preview helper、VAD 本地资产同步、FilteredAudioRenderer 内真实播放观测这几块都和本 PR 主题相关,没有发现需要阻塞合并的额外问题。

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

Claude finished @jinfeng66's task in 2m 12s —— View job


Todo

  • 拉取上下文与最新 diff
  • 审查本轮新增 commit(重点确认上轮 P1 room-input stop 问题是否修复)
  • 输出 review 结论

Review 结论

通过

本轮新增的 3 个 commit(f3159a9 eba3d05 eac6132)只针对上一轮 review 的 P1 做了修复,未引入无关改动:

  • lib/session-stop.ts 新增的 resolveRoomInputStopUrls() 现在先用 resolveRoleInputDevices() 解出实际选中的 audioInputDevice/visionInputDevice,再用 usesServerRoomInputDevice() 过滤——只有 role 落在 xunfei/generic 时才会把对应 stop URL 加入候选集,primebot 不再产生任何 room-input stop 副作用(selectedServerDevices 为空时直接返回 [])。
  • mixed 场景下也只对实际选中的 server role 生成 frontdesk/face/generic stop URL,不会再对未选中的 role 发起 stop。
  • 同时把 DEFAULT_ROLE_INPUT_DEVICE/VALID_INPUT_DEVICES/SERVER_ROOM_INPUT_DEVICES/normalizeInputSource/resolveRoleInputDevices 抽到新的 lib/input-device-config.tsapp-config.tsapp/api/session/stop/route.ts 都改为复用同一份实现,一并解决了上上轮遗留的“常量/归一化逻辑两处重复”的 P2。
  • tests/session-stop.test.mjs 新增了 primebot 场景返回空数组、mixed 场景仅 stop 已选中 server role(xunfei 音频 + browser 视觉 → 只 stop xunfei 相关 URL,忽略 vision/generic)两个用例,覆盖了上轮 review 指出的两种跨设备副作用场景。

之前两轮 P1(远端播放事件语义、unpublishAudio 清理顺序)在上上轮已确认修复,本轮 diff 未涉及相关文件,未回归。

问题及建议

未发现需要阻塞合并的问题。残余风险:作者在评论中已说明保留的 3 个 P2(audioContext.resume() 失败仅 console.warn、backend marker name 缺少长度上限、sanitizeObservabilityAttributes 未过滤数组)留作后续 hardening PR,属于合理取舍,不影响本次合并。

@jinfeng66 jinfeng66 dismissed stale reviews from lanyue-llk and lanyue-llk July 1, 2026 09:24

Stale review on an old commit; requested changes have been addressed in later commits and the latest automated review on eac6132 passes.

@lanyue-llk lanyue-llk merged commit 09a2500 into lex-main Jul 1, 2026
2 checks passed
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.

3 participants