From 5d40657aef2bad7beb9ebe9f6084bf1b6b9ee11e Mon Sep 17 00:00:00 2001
From: patrick-motsch
Date: Wed, 18 Feb 2026 00:12:48 +0100
Subject: [PATCH] fix: dynamic bot name in SPEECH_TEAMS prompt + phonetic name
trigger
Co-authored-by: Cursor
---
modules/features/teamsbot/service.py | 23 ++++++++++++++++++++-
modules/services/serviceAi/mainServiceAi.py | 16 ++++++++++----
2 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/modules/features/teamsbot/service.py b/modules/features/teamsbot/service.py
index 6f54927b..df21d8ff 100644
--- a/modules/features/teamsbot/service.py
+++ b/modules/features/teamsbot/service.py
@@ -530,10 +530,31 @@ class TeamsbotService:
# Bot name mentioned -> immediate trigger (OVERRIDES cooldown)
botNameLower = self.config.botName.lower()
- if botNameLower in 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)
+ 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
+
# Cooldown check (only for non-name triggers)
if timeSinceLastCall < self.config.triggerCooldownSeconds:
logger.debug(f"Trigger: Cooldown active ({timeSinceLastCall:.1f}s < {self.config.triggerCooldownSeconds}s)")
diff --git a/modules/services/serviceAi/mainServiceAi.py b/modules/services/serviceAi/mainServiceAi.py
index 0781086d..ab45b49f 100644
--- a/modules/services/serviceAi/mainServiceAi.py
+++ b/modules/services/serviceAi/mainServiceAi.py
@@ -328,16 +328,24 @@ class AiService:
Build the specialized system prompt for SPEECH_TEAMS meeting analysis.
Combines a fixed base prompt with user-configurable instructions.
"""
+ # Extract first name for examples (e.g. "Nyla" from "Nyla Larsson")
+ botFirstName = botName.split()[0] if " " in botName else botName
+
basePrompt = f"""Du bist "{botName}", ein AI-Teilnehmer in einem Microsoft Teams Meeting.
Analysiere das folgende Transkript und entscheide, ob du antworten sollst.
SPRACHE: Das Transkript kann in verschiedenen Sprachen sein. Antworte immer in der Sprache des letzten Sprechers der dich angesprochen hat. Wenn jemand sagt "let's talk German" oder "sprich deutsch", wechsle die Sprache entsprechend.
+WICHTIG - SPRACHERKENNUNG: Das Transkript stammt aus einer automatischen Spracherkennung (Live Captions).
+Dein Name "{botFirstName}" kann VERZERRT transkribiert werden, z.B. als aehnlich klingende Varianten
+(z.B. "{botFirstName}" koennte als "Naila", "Neela", "Nila", "Sheila" etc. erscheinen).
+Wenn ein Wort im Transkript PHONETISCH AEHNLICH zu "{botFirstName}" klingt und im Kontext einer Anrede steht, bist du gemeint.
+
WANN ANTWORTEN:
REGEL 1 (HOECHSTE PRIORITAET - NUR wenn direkt angesprochen):
-Antworte NUR wenn dein Name "{botName}" (oder Varianten wie Shelly, shelly) DIREKT im aktuellsten Transkript-Segment vorkommt.
-Beispiele wo du antworten MUSST: "Shelly, was denkst du?", "Hey Shelly", "Shelly please introduce yourself"
+Antworte NUR wenn dein Name "{botFirstName}" (oder phonetisch aehnliche Varianten durch Spracherkennung) DIREKT im aktuellsten Transkript-Segment vorkommt.
+Beispiele wo du antworten MUSST: "{botFirstName}, was denkst du?", "Hey {botFirstName}", "{botFirstName} please introduce yourself"
Beispiele wo du NICHT antworten darfst: Jemand spricht ueber ein Thema ohne dich zu adressieren.
REGEL 2 (NUR bei direkter Frage an dich):
@@ -361,8 +369,8 @@ ANTWORT-STIL (wenn du antwortest):
STOP-ERKENNUNG:
Wenn jemand dich bittet aufzuhoeren, still zu sein, zu stoppen, oder nicht mehr zu reden
-(in JEDER Sprache, z.B. "Shelly stop", "Shelly sei still", "Shelly halt", "Shelly be quiet",
-"Shelly shut up", "Shelly arrete", etc.), dann setze detectedIntent auf "stop" und
+(in JEDER Sprache, z.B. "{botFirstName} stop", "{botFirstName} sei still", "{botFirstName} halt", "{botFirstName} be quiet",
+"{botFirstName} shut up", "{botFirstName} arrete", etc.), dann setze detectedIntent auf "stop" und
shouldRespond auf false. Du musst NICHT antworten wenn jemand dich stoppt."""
# Append user-configured instructions if provided