fix(teamsbot): AI prompt priority rules, bot-name trigger overrides cooldown

- SPEECH_TEAMS prompt: Rule 1 (bot name mentioned) now has highest priority
  and ALWAYS triggers a response, even for greetings/smalltalk
- Bot-name detection in transcript overrides cooldown timer (immediate trigger)
- Added multilingual instruction: AI responds in the language it's addressed in
- Voice interface: clean camelCase mapping (audio_content -> audioContent)
- Config save: added "config" to allowed update fields in interfaceFeatures
- Default TTS voices for common languages in connectorVoiceGoogle

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
patrick-motsch 2026-02-15 11:48:44 +01:00
parent e01c6dcb95
commit 91425809c3
2 changed files with 24 additions and 21 deletions

View file

@ -370,19 +370,19 @@ class TeamsbotService:
- Cooldown respected - Cooldown respected
""" """
now = time.time() now = time.time()
# Cooldown check
timeSinceLastCall = now - self._lastAiCallTime timeSinceLastCall = now - self._lastAiCallTime
# Bot name mentioned -> immediate trigger (OVERRIDES cooldown)
botNameLower = self.config.botName.lower()
if botNameLower in transcriptText.lower():
logger.info(f"Trigger: Bot name '{self.config.botName}' detected in transcript (overrides cooldown): '{transcriptText[:60]}...'")
return True
# Cooldown check (only for non-name triggers)
if timeSinceLastCall < self.config.triggerCooldownSeconds: if timeSinceLastCall < self.config.triggerCooldownSeconds:
logger.debug(f"Trigger: Cooldown active ({timeSinceLastCall:.1f}s < {self.config.triggerCooldownSeconds}s)") logger.debug(f"Trigger: Cooldown active ({timeSinceLastCall:.1f}s < {self.config.triggerCooldownSeconds}s)")
return False return False
# Bot name mentioned -> immediate trigger
botNameLower = self.config.botName.lower()
if botNameLower in transcriptText.lower():
logger.info(f"Trigger: Bot name '{self.config.botName}' detected in transcript: '{transcriptText[:60]}...'")
return True
# Periodic trigger # Periodic trigger
if timeSinceLastCall >= self.config.triggerIntervalSeconds: if timeSinceLastCall >= self.config.triggerIntervalSeconds:
logger.info(f"Trigger: Periodic interval ({self.config.triggerIntervalSeconds}s) elapsed ({timeSinceLastCall:.1f}s since last call)") logger.info(f"Trigger: Periodic interval ({self.config.triggerIntervalSeconds}s) elapsed ({timeSinceLastCall:.1f}s since last call)")

View file

@ -329,23 +329,26 @@ class AiService:
Combines a fixed base prompt with user-configurable instructions. Combines a fixed base prompt with user-configurable instructions.
""" """
basePrompt = f"""Du bist "{botName}", ein AI-Teilnehmer in einem Microsoft Teams Meeting. basePrompt = f"""Du bist "{botName}", ein AI-Teilnehmer in einem Microsoft Teams Meeting.
Analysiere das folgende Transkript der laufenden Diskussion und entscheide, ob du antworten sollst. Analysiere das folgende Transkript und entscheide, ob du antworten sollst.
ANTWORTE NUR wenn: WICHTIG: Das Transkript kann in verschiedenen Sprachen sein (Deutsch, Englisch, etc.) weil die Spracherkennung die Sprache nicht immer korrekt erkennt. Antworte immer in der Sprache, in der du angesprochen wirst.
1. Du direkt angesprochen wirst (z.B. "{botName}, was denkst du?" oder "Hey {botName}")
2. Eine explizite Frage an die Runde gestellt wird, die du sachlich beantworten kannst
3. Du einen wertvollen, nicht-offensichtlichen Beitrag zur Diskussion hast
ANTWORTE NICHT wenn: REGEL 1 (HOECHSTE PRIORITAET - IMMER ANTWORTEN):
- Die Teilnehmer normal miteinander sprechen ohne dich einzubeziehen Wenn dein Name "{botName}" oder eine aehnliche Anrede (Shelly, shelly, SHELLY, etc.) im Transkript vorkommt, MUSST du IMMER antworten, egal ob es Smalltalk, eine Frage oder eine Begruessung ist. Du bist ein freundlicher Meeting-Teilnehmer.
- Die Diskussion keinen Input von dir benoetigt
- Du nur wiederholen wuerdest, was bereits gesagt wurde REGEL 2 (ANTWORTEN wenn sinnvoll):
- Es sich um Smalltalk oder Begruessung handelt - Eine explizite Frage an die Runde gestellt wird, die du sachlich beantworten kannst
- Du einen wertvollen Beitrag zur Diskussion hast
REGEL 3 (NICHT ANTWORTEN):
- Die Teilnehmer normal miteinander sprechen OHNE deinen Namen zu nennen
- Die Diskussion keinen Input von dir benoetigt und du nicht angesprochen wirst
ANTWORT-STIL: ANTWORT-STIL:
- Halte dich kurz und praezise (max 2-3 Saetze fuer Sprache) - Halte dich kurz und praezise (max 2-3 Saetze)
- Sei professionell aber natuerlich - Sei freundlich, professionell und natuerlich
- Beziehe dich konkret auf das Gesagte""" - Bei Begruessung: Antworte herzlich zurueck
- Bei Fragen: Beantworte sachlich und konkret"""
# Append user-configured instructions if provided # Append user-configured instructions if provided
if userSystemPrompt and userSystemPrompt.strip(): if userSystemPrompt and userSystemPrompt.strip():