Skip to content

perf: Prewarm LiveAvatar browser sessions#16

Open
jiejuncai-ly wants to merge 21 commits into
lex-mainfrom
perf/liveavatar-session-prewarm-20260713
Open

perf: Prewarm LiveAvatar browser sessions#16
jiejuncai-ly wants to merge 21 commits into
lex-mainfrom
perf/liveavatar-session-prewarm-20260713

Conversation

@jiejuncai-ly

@jiejuncai-ly jiejuncai-ly commented Jul 14, 2026

Copy link
Copy Markdown

Goal

在用户点击 Start 之前完成 LiveKit Room、Agent dispatch、room_audio_inputroom_video_input 的预热,并让浏览器 Start 复用已建立的 Session,缩短首屏视频与人脸检测等待时间。

本 PR 与 lex-voice#226 配套。

Design

1. 服务端 prewarm

  • 新增 POST /api/session/prewarm,使用 Gateway 注入的单 Sandbox secret 做服务端授权。
  • 同一 Session 的 prewarm 在执行中或成功后不可重复消费;失败会释放 guard,但 Gateway 对不确定响应仍按 fail-closed 回收整个 Sandbox。
  • 抽离共享 dispatch 服务,让 prewarm 与正常 Start 复用同一 LiveKit dispatch 和 readiness 判定。
  • readiness 必须同时看到 room_audio_inputroom_video_input,但不要求浏览器视频首帧已经发布。

2. Browser Start

  • Browser 房间连接后并行启动本地媒体与 Agent dispatch,不再串行等待两条链路。
  • 已有 dispatch 会被复用;取消、超时和并发调用共享同一生命周期,避免重复创建 Agent。
  • 保持真实首帧边界:只有浏览器拿到有效视频帧后,后端才发布 room_video

3. 路径与 Sandbox 兼容

  • Next 静态资源、logo、VAD/ONNX 资源和浏览器 API 使用 app-relative/session-aware 路径。
  • 同一 build 兼容本地根路径、Gateway /s/<slug> 和 CubeSandbox /proxy/4003/ 前缀。
  • 当前生产 Sandbox 仍由 lex-voice 的 ui_proxy.py 对外监听 4003,再转发到监听 127.0.0.1:4103 的 Next;这是动态 Cube 路径的兼容边界,不应从 Template 移除。

4. 超时与可观测性

  • 常规 dispatch 保持既有 8s 边界。
  • prewarm 总预算为 45s;Agent worker readiness 上限为 30s,并与 dispatch 共用同一个总 deadline。
  • Gateway 外层默认预算为 60s,覆盖前端预算与网络/清理余量。
  • prewarm 返回 allowlist 后的 readiness 与 timings;错误会标明当前 phase,不回传 secret 或内部对象。

Validation

  • 当前 GitHub Actions:155 passed
  • ESLint:通过。
  • Next production build:通过。
  • 路径测试覆盖本地、Gateway 和 CubeSandbox 前缀;prewarm 测试覆盖授权、单次消费、失败释放、并发共享、总预算、worker 上限、readiness 和阶段 timing。
  • 此前内网 Sandbox HIL 已验证点击前 input participant ready、点击后发布有效 room_video 且未出现绿色/紫色噪点。配套 lex-voice 最新 bootstrap/cancellation 修复合入后仍需重跑真实双环境 HIL。

Risk and rollout

Merge / deploy order

@jiejuncai-ly
jiejuncai-ly marked this pull request as ready for review July 14, 2026 03:47
@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 已逐项核对:

  • prewarmRoomSession 等待 room_audio_input / room_video_input 不改。browser 模式仍通过 lex-voice 的 browser profile 启动这两个 Room Input 服务参与者;它们先入房并等待浏览器原始轨道。usesServerRoomInputDevice() 只决定用户启动阶段是否再次要求 video readiness,不能据此推断 browser 模式没有这两个参与者。
  • 本地媒体快速失败仍等待 dispatch 的问题已在 d813831 修复:失败时立即 cancelAgentSessionStart(sessionId),中止 dispatch fetch,再复用原有统一远端清理路径。
  • session identity 的隐式漂移已在 9d160e4 修复:LIVEAVATAR_VOICE_SESSION_ID 进入 appConfig.voiceSessionId,且远端 UI config 不能覆盖。AGENT_NAME 由同一进程 env 同源读取,LiveKit room name 则由 canonical session id 推导,因此不再增加另一套配置入口。

验证:129 tests passed,lint passed,production build passed(仅保留已有 ONNX dynamic-require warning)。真实 cloud template 的 /api/session/prewarm HIL 仍按部署 gate 执行。

@jiejuncai-ly

jiejuncai-ly commented Jul 16, 2026

Copy link
Copy Markdown
Author

更新:routing 已合入,本 PR 已基于最新 lex-main 恢复并完成重新移植与测试;当前分支是正式候选,不再是撤下状态。

@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.

@github-actions

This comment has been minimized.

@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown

Claude finished @jiejuncai-ly's task in 5m 13s —— View job


Review 结论

有条件通过

(说明:本次沙箱环境无 node_modules 且无法访问网络安装依赖,未能实际执行 pnpm test / lint / build,以下结论基于对全部变更文件源码的静读审查。核心链路 session-dispatch-service.tsprewarm/route.tsprewarm-use-guard.tssession-registry.tsuseRoom.tsuseBrowserSourceClient.ts 均已通读,前几轮 review 中指出的三个问题——本地媒体快速失败未取消 dispatch、session identity 隐式漂移、room_audio_input/room_video_input 参与者语义——均已在当前代码中正确落地。)

问题及建议

  • [P2] app/api/session/session-dispatch-service.ts:595-631runWithinPrewarmDeadline 中,若 operationPromise 恰好在 deadline 边界前完成但 Date.now() >= deadline 判断为真时,会丢弃已经成功的结果并按超时处理(额外产生一次未被感知的后台 room/dispatch 副作用)。属于极端时序场景,非阻塞项,可考虑放宽为“结果已到手优先返回”。
  • [P2] lib/frontend-vad-observer.ts:48-63 + hooks/useBrowserSourceClient.ts:157-159resolveVadAssetBasePaths 直接把整个 window.location.pathname 当作 session 前缀拼接 /vad-web/。当前应用是单路由页面,行为正确;但如果未来在同一入口下增加客户端子路由,该路径会被误拼成 <pathname>/vad-web/ 导致 404。建议在实现里加注释或改为只截取到 sandboxId/slug 段,避免后续路由变化时静默失效。
  • [P2] app/api/session/prewarm/prewarm-use-guard.ts:12-14prewarmUseStatesglobalThis 级 Map,completed 状态的 key 永不清理。设计注释已说明这是有意为之(Gateway 每 sandbox 一个新 UUID,进程生命周期短),在当前部署模型下可接受,仅在未来若单进程长期承载大量 sandbox 会话时需要重新评估。

残余风险:未能在本地跑通 142 项前端测试与 production build,建议在 CI 结果(View job run)通过后再合并;上述三条均为非阻塞的健壮性/可维护性建议。

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