Add Resemble Detect and Signal plugin#6115
Conversation
| if self._opts.mode == "sampled": | ||
| if forced: | ||
| self._force_pending = False | ||
| else: | ||
| self._samples_taken += 1 | ||
| cooldown_until = stream_pos + self._opts.sample_interval_seconds | ||
| if self._samples_taken >= self._opts.samples: | ||
| # settle the ambient verdict but stay alive for check_now() | ||
| await self._flush_and_emit_verdict() |
There was a problem hiding this comment.
π΄ _force_pending never cleared in continuous and first_n modes after check_now()
When check_now() is called, _force_pending is set to True (line 497). However, _force_pending is only reset to False inside the if self._opts.mode == "sampled" block at line 704-706. In continuous or first_n modes, this flag is never cleared, so every subsequent window after the first check_now() is permanently treated as forced=True.
This has two concrete impacts:
- Silence detection permanently bypassed:
_is_silence(window) and not forcedatdetect.py:686will never skip silent windows again, sending unnecessary API requests for every silent window. - Incorrect
synthetic_detectedemission: Ifforce_immediate_fake=True, a single fake-scoring window triggerssynthetic_detectedatdetect.py:821-822, bypassing the configured agreement policy (e.g., 2-of-3). This defeats the purpose of the agreement window in high-security mode.
| if self._opts.mode == "sampled": | |
| if forced: | |
| self._force_pending = False | |
| else: | |
| self._samples_taken += 1 | |
| cooldown_until = stream_pos + self._opts.sample_interval_seconds | |
| if self._samples_taken >= self._opts.samples: | |
| # settle the ambient verdict but stay alive for check_now() | |
| await self._flush_and_emit_verdict() | |
| if forced: | |
| self._force_pending = False | |
| if self._opts.mode == "sampled": | |
| if not forced: | |
| self._samples_taken += 1 | |
| cooldown_until = stream_pos + self._opts.sample_interval_seconds | |
| if self._samples_taken >= self._opts.samples: | |
| # settle the ambient verdict but stay alive for check_now() | |
| await self._flush_and_emit_verdict() |
Was this helpful? React with π or π to provide feedback.
| def _has_confirmed_fake(self) -> bool: | ||
| if not self._results: | ||
| return False | ||
| recent = self._results[-self._opts.agreement_window :] | ||
| fake_results = [r for r in recent if r.aggregated_score >= self._opts.fake_threshold] | ||
| return len(fake_results) >= self._opts.min_fake_results |
There was a problem hiding this comment.
π© Out-of-order result appends from concurrent _analyze_window tasks
Windows are spawned as independent tasks (detect.py:693-702), and results are appended to self._results in completion order, not submission order. This means _has_confirmed_fake() at detect.py:812 applies the agreement window over results in completion order, which may not match the chronological window order if some API calls are slower than others. For the 2-of-3 agreement policy this is likely acceptable (checking recent completions rather than chronological windows), but it's a subtle behavioral property worth being aware of.
Was this helpful? React with π or π to provide feedback.
Summary
livekit-plugins-resembleValidation
ruff format livekit-plugins/livekit-plugins-resemble/livekit/plugins/resemble/signal.pyruff check livekit-plugins/livekit-plugins-resemble/livekit/plugins/resemble/signal.py--warn-return-anyonsignal.pygit diff --checkNote: the external Devin review check is still pending.