From 269b70481214db6dd490d0e973101bf2d6718517 Mon Sep 17 00:00:00 2001
From: patrick-motsch
Date: Fri, 27 Feb 2026 22:38:29 +0100
Subject: [PATCH] Teamsbot: lower audio RMS threshold, add 10s min cooldown for
name-based AI triggers
Made-with: Cursor
---
modules/features/teamsbot/service.py | 58 ++++++++++++++++------------
1 file changed, 34 insertions(+), 24 deletions(-)
diff --git a/modules/features/teamsbot/service.py b/modules/features/teamsbot/service.py
index e481bf86..e1ac6eda 100644
--- a/modules/features/teamsbot/service.py
+++ b/modules/features/teamsbot/service.py
@@ -450,7 +450,7 @@ class TeamsbotService:
if captureDiagnostics and captureDiagnostics.get("rms") is not None:
try:
rmsVal = float(captureDiagnostics.get("rms"))
- if rmsVal < 0.0015:
+ if rmsVal < 0.0003:
logger.debug(f"[AudioChunk] Skipping silent audio ({len(audioBytes)} bytes, rms={rmsVal:.6f})")
return
except Exception:
@@ -763,32 +763,42 @@ class TeamsbotService:
now = time.time()
timeSinceLastCall = now - self._lastAiCallTime
- # Bot name mentioned -> immediate trigger (OVERRIDES cooldown)
+ # Bot name detection — overrides the periodic cooldown but still
+ # respects a minimum re-trigger interval to prevent caption-event
+ # spam (multiple caption snapshots of the same utterance).
+ minNameRetriggerSeconds = 10
botNameLower = self.config.botName.lower()
transcriptLower = transcriptText.lower()
- if botNameLower in transcriptLower:
- logger.info(f"Trigger: Bot name '{self.config.botName}' detected in transcript (overrides cooldown): '{transcriptText[:60]}...'")
- return True
- # Also check first name and phonetically similar words (speech recognition artifacts)
- botFirstName = botNameLower.split()[0] if " " in botNameLower else botNameLower
- if len(botFirstName) >= 3:
- for word in transcriptLower.split():
- # Strip punctuation from word
- cleanWord = word.strip(".,!?:;\"'()[]")
- if not cleanWord or len(cleanWord) < 3:
- continue
- # Exact first name match
- if cleanWord == botFirstName:
- logger.info(f"Trigger: Bot first name '{botFirstName}' detected: '{transcriptText[:60]}...'")
- return True
- # Simple phonetic similarity: same first letter, similar length, high character overlap
- if cleanWord[0] == botFirstName[0] and abs(len(cleanWord) - len(botFirstName)) <= 2:
- common = sum(1 for c in set(botFirstName) if c in cleanWord)
- similarity = common / max(len(set(botFirstName)), len(set(cleanWord)))
- if similarity >= 0.6:
- logger.info(f"Trigger: Phonetically similar to '{botFirstName}' -> '{cleanWord}' (sim={similarity:.2f}): '{transcriptText[:60]}...'")
- return True
+ nameDetected = False
+ if botNameLower in transcriptLower:
+ nameDetected = True
+ else:
+ botFirstName = botNameLower.split()[0] if " " in botNameLower else botNameLower
+ if len(botFirstName) >= 3:
+ for word in transcriptLower.split():
+ cleanWord = word.strip(".,!?:;\"'()[]")
+ if not cleanWord or len(cleanWord) < 3:
+ continue
+ if cleanWord == botFirstName:
+ nameDetected = True
+ break
+ if cleanWord[0] == botFirstName[0] and abs(len(cleanWord) - len(botFirstName)) <= 2:
+ common = sum(1 for c in set(botFirstName) if c in cleanWord)
+ similarity = common / max(len(set(botFirstName)), len(set(cleanWord)))
+ if similarity >= 0.6:
+ nameDetected = True
+ break
+
+ if nameDetected:
+ if timeSinceLastCall < minNameRetriggerSeconds:
+ logger.debug(
+ f"Trigger: Bot name detected but within re-trigger cooldown "
+ f"({timeSinceLastCall:.1f}s < {minNameRetriggerSeconds}s)"
+ )
+ return False
+ logger.info(f"Trigger: Bot name detected in transcript: '{transcriptText[:60]}...'")
+ return True
# Cooldown check (only for non-name triggers)
if timeSinceLastCall < self.config.triggerCooldownSeconds: