Teamsbot: lower audio RMS threshold, add 10s min cooldown for name-based AI triggers

Made-with: Cursor
This commit is contained in:
patrick-motsch 2026-02-27 22:38:29 +01:00
parent 0ee86070bd
commit 269b704812

View file

@ -450,7 +450,7 @@ class TeamsbotService:
if captureDiagnostics and captureDiagnostics.get("rms") is not None: if captureDiagnostics and captureDiagnostics.get("rms") is not None:
try: try:
rmsVal = float(captureDiagnostics.get("rms")) 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})") logger.debug(f"[AudioChunk] Skipping silent audio ({len(audioBytes)} bytes, rms={rmsVal:.6f})")
return return
except Exception: except Exception:
@ -763,32 +763,42 @@ class TeamsbotService:
now = time.time() now = time.time()
timeSinceLastCall = now - self._lastAiCallTime 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() botNameLower = self.config.botName.lower()
transcriptLower = transcriptText.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) nameDetected = False
botFirstName = botNameLower.split()[0] if " " in botNameLower else botNameLower if botNameLower in transcriptLower:
if len(botFirstName) >= 3: nameDetected = True
for word in transcriptLower.split(): else:
# Strip punctuation from word botFirstName = botNameLower.split()[0] if " " in botNameLower else botNameLower
cleanWord = word.strip(".,!?:;\"'()[]") if len(botFirstName) >= 3:
if not cleanWord or len(cleanWord) < 3: for word in transcriptLower.split():
continue cleanWord = word.strip(".,!?:;\"'()[]")
# Exact first name match if not cleanWord or len(cleanWord) < 3:
if cleanWord == botFirstName: continue
logger.info(f"Trigger: Bot first name '{botFirstName}' detected: '{transcriptText[:60]}...'") if cleanWord == botFirstName:
return True nameDetected = True
# Simple phonetic similarity: same first letter, similar length, high character overlap break
if cleanWord[0] == botFirstName[0] and abs(len(cleanWord) - len(botFirstName)) <= 2: if cleanWord[0] == botFirstName[0] and abs(len(cleanWord) - len(botFirstName)) <= 2:
common = sum(1 for c in set(botFirstName) if c in cleanWord) common = sum(1 for c in set(botFirstName) if c in cleanWord)
similarity = common / max(len(set(botFirstName)), len(set(cleanWord))) similarity = common / max(len(set(botFirstName)), len(set(cleanWord)))
if similarity >= 0.6: if similarity >= 0.6:
logger.info(f"Trigger: Phonetically similar to '{botFirstName}' -> '{cleanWord}' (sim={similarity:.2f}): '{transcriptText[:60]}...'") nameDetected = True
return 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) # Cooldown check (only for non-name triggers)
if timeSinceLastCall < self.config.triggerCooldownSeconds: if timeSinceLastCall < self.config.triggerCooldownSeconds: