testRunningModes#633
Conversation
Diagnostic-only PR. Adds three buttons (IMAGE / VIDEO / LIVE_STREAM) to the smart-selfie capture screen that rebuild the FaceLandmarker with the selected runningMode and surface creation errors inline. Notes: - JS bindings only declare RunningMode = 'IMAGE' | 'VIDEO'. LIVE_STREAM exists in the Java API but not the web build, so it is passed through as a probe and is expected to error at create time. - IMAGE uses detect(); VIDEO/LIVE_STREAM use detectForVideo(). - Singleton cache is now keyed by runningMode; old instance is closed before rebuilding.
🔍 Semgrep Security Scan Results✅ No security findings detected by |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
| const setRunningMode = async (mode: MediapipeRunningMode) => { | ||
| if (mode === runningMode.value) return; | ||
| stopDetectionLoop(); | ||
| resetFaceDetectionState(); | ||
| runningMode.value = mode; | ||
| faceLandmarkerRef.current = null; | ||
| await initializeFaceLandmarker(); | ||
| setupCanvas(); | ||
| startDetectionLoop(); | ||
| }; |
There was a problem hiding this comment.
Suggestion: setRunningMode is async but has no error handling. If initializeFaceLandmarker() throws (e.g. when selecting LIVE_STREAM), the subsequent setupCanvas() and startDetectionLoop() will still execute with a null faceLandmarkerRef, likely causing a runtime crash in the detection loop. [possible issue, importance: 7]
| const setRunningMode = async (mode: MediapipeRunningMode) => { | |
| if (mode === runningMode.value) return; | |
| stopDetectionLoop(); | |
| resetFaceDetectionState(); | |
| runningMode.value = mode; | |
| faceLandmarkerRef.current = null; | |
| await initializeFaceLandmarker(); | |
| setupCanvas(); | |
| startDetectionLoop(); | |
| }; | |
| const setRunningMode = async (mode: MediapipeRunningMode) => { | |
| if (mode === runningMode.value) return; | |
| stopDetectionLoop(); | |
| resetFaceDetectionState(); | |
| runningMode.value = mode; | |
| faceLandmarkerRef.current = null; | |
| try { | |
| await initializeFaceLandmarker(); | |
| if (!faceLandmarkerRef.current) return; | |
| setupCanvas(); | |
| startDetectionLoop(); | |
| } catch (error) { | |
| runningModeError.value = | |
| error instanceof Error ? error.message : String(error); | |
| } | |
| }; |
| const results = | ||
| runningMode.value === 'IMAGE' | ||
| ? landmarker.detect(detectionSource) | ||
| : landmarker.detectForVideo(detectionSource, performance.now()); |
There was a problem hiding this comment.
Suggestion: When runningMode is LIVE_STREAM, calling detectForVideo on a landmarker configured with LIVE_STREAM will throw because MediaPipe expects a callback-based API for that mode. There's no guard or try/catch around this dispatch, so the detection loop will crash and stop entirely without surfacing the error to the user. [possible issue, importance: 7]
| const results = | |
| runningMode.value === 'IMAGE' | |
| ? landmarker.detect(detectionSource) | |
| : landmarker.detectForVideo(detectionSource, performance.now()); | |
| let results; | |
| try { | |
| results = | |
| runningMode.value === 'IMAGE' | |
| ? landmarker.detect(detectionSource) | |
| : landmarker.detectForVideo(detectionSource, performance.now()); | |
| } catch (detectionError) { | |
| runningModeError.value = | |
| detectionError instanceof Error ? detectionError.message : String(detectionError); | |
| stopDetectionLoop(); | |
| return; | |
| } |
There was a problem hiding this comment.
Pull request overview
Adds a diagnostic-only running-mode selector to the Smart Selfie capture flow to rebuild the MediaPipe FaceLandmarker as IMAGE, VIDEO, or a probe LIVE_STREAM mode, and surfaces running-mode creation errors inline. This fits into the web-components Smart Selfie capture pipeline by modifying the MediaPipe singleton lifecycle and the face-detection loop dispatch method.
Changes:
- Introduces a
MediapipeRunningModetype + default mode and stores the selected mode in the MediaPipe singleton cache. - Adds a running-mode button bar + inline error surface on the SmartSelfie capture screen.
- Updates
useFaceCaptureto rebuild the landmarker on mode changes and to usedetect()for IMAGE vsdetectForVideo()for VIDEO/LIVE_STREAM.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| packages/web-components/lib/components/selfie/src/smartselfie-capture/utils/mediapipeManager.ts | Adds runningMode typing/default and attempts to key the singleton instance by runningMode (with teardown/rebuild). |
| packages/web-components/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx | Adds diagnostic UI controls (mode buttons + error text) and corresponding styles. |
| packages/web-components/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts | Tracks runningMode state, reinitializes the landmarker on toggle, and dispatches detection calls based on mode. |
Comments suppressed due to low confidence (1)
packages/web-components/lib/components/selfie/src/smartselfie-capture/utils/mediapipeManager.ts:266
getMediapipeInstancereturns an in-flightmediapipeGlobal.loadingpromise without checking whether it was started with the requestedrunningMode. If the user toggles modes while the first create is still loading, the caller can receive an instance configured for the previous mode, leavingmediapipeGlobal.runningMode/runningMode.valueout of sync and potentially calling the wrong detect API for the configured graph. Consider keyingloadingby runningMode (or storingloadingModeand rebuilding once the prior load resolves) so each mode request is guaranteed to receive a matching instance.
if (
mediapipeGlobal.loaded &&
mediapipeGlobal.instance &&
mediapipeGlobal.runningMode === runningMode
) {
return mediapipeGlobal.instance;
}
if (mediapipeGlobal.loading) {
return mediapipeGlobal.loading;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -138,6 +148,19 @@ export const useFaceCapture = ({ | |||
| startFallbackTimer(); | |||
| }; | |||
| <div className="running-mode-bar" role="group" aria-label="MediaPipe running mode"> | ||
| {(['IMAGE', 'VIDEO', 'LIVE_STREAM'] as const).map((mode) => ( |
| import { getMediapipeInstance } from '../utils/mediapipeManager'; | ||
| import type { MediapipeRunningMode } from '../utils/mediapipeManager'; | ||
| import { DEFAULT_MEDIAPIPE_RUNNING_MODE } from '../utils/mediapipeManager'; |
| {(['IMAGE', 'VIDEO', 'LIVE_STREAM'] as const).map((mode) => ( | ||
| <button | ||
| key={mode} | ||
| type="button" |
|
This branch has been deployed to s3 / cloudfront. ✅ Preview URL for Smart Camera Web: ✅ Preview URL for Embed: ✅ Preview URL for Web Client (Sandbox): ✅ Preview URL for Web Client (Production): |
|
This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
|
This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
User description
Diagnostic-only PR. Adds three buttons (IMAGE / VIDEO / LIVE_STREAM) to the smart-selfie capture screen that rebuild the FaceLandmarker with the selected runningMode and surface creation errors inline.
Notes:
RunningMode = 'IMAGE' | 'VIDEO'. LIVE_STREAM exists in the Java API but not the web build, so it is passed through as a probe and is expected to error at create time.detect(); VIDEO/LIVE_STREAM usedetectForVideo().PR Type
Tests, Enhancement
Description
Add diagnostic RunningMode toggle (IMAGE/VIDEO/LIVE_STREAM) to selfie capture UI
Rebuild FaceLandmarker singleton keyed by selected runningMode
Dispatch detection via
detect()ordetectForVideo()based on modeSurface runningMode creation errors inline on the capture screen
Diagram Walkthrough
File Walkthrough
SmartSelfieCapture.tsx
Add RunningMode toggle UI and error displaypackages/web-components/lib/components/selfie/src/smartselfie-capture/SmartSelfieCapture.tsx
selecting MediaPipe running mode
text
useFaceCapture.ts
Support dynamic RunningMode switching in face capture hookpackages/web-components/lib/components/selfie/src/smartselfie-capture/hooks/useFaceCapture.ts
runningModeandrunningModeErrorsignals to hook statesetRunningModefunction that tears down and rebuilds theFaceLandmarker
initializeFaceLandmarkerto passrunningModeand check cachevalidity
detect()for IMAGE mode anddetectForVideo()otherwisemediapipeManager.ts
Key MediaPipe singleton by runningMode with teardown logicpackages/web-components/lib/components/selfie/src/smartselfie-capture/utils/mediapipeManager.ts
MediapipeRunningModetype andDEFAULT_MEDIAPIPE_RUNNING_MODEconstant
runningModefield for cacheinvalidation
getMediapipeInstanceto accept arunningModeparameter andclose/rebuild on mode change
runningMode(with cast for LIVE_STREAM) toFaceLandmarker.createFromOptions