wiki/b-reference/teams-bot/architecture.md
ValueOn AG d4095db4f2 fixes
2026-04-25 01:13:24 +02:00

7.2 KiB
Raw Blame History

Teams Meeting Bot -- Architektur

Überblick

AI-gesteuerter Meeting-Bot für Microsoft Teams. Tritt Meetings als regulärer Teilnehmer bei (Browser-Automation via Playwright/Chromium), erfasst Live-Transkripte, reagiert per Sprache (TTS) und/oder Chat. Kein Teams-Graph-SDK nötig -- funktioniert mandantenübergreifend ohne Admin-Approval.

System-Architektur

┌────────────┐      SSE       ┌──────────────┐    WebSocket    ┌─────────────┐
│  Frontend   │◄──────────────│   Gateway     │◄───────────────│  Bot Service │
│  (Nyla UI)  │               │  (AI, TTS,    │   HTTP (join/  │  (Playwright │
│             │               │   Sessions)   │    leave)      │   Chromium)  │
└────────────┘               └──────────────┘               └─────────────┘
Verbindung Protokoll Zweck
Gateway ↔ Bot WebSocket Echtzeit: Transkripte, Chat, Audio, Status
Gateway → Bot HTTP Session-Steuerung (join, leave, status)
Frontend ← Gateway SSE Live-Transkript-Stream für UI

Kernfähigkeiten

  • Live Transcription: Erfasst Untertitel mit Sprecher-Zuordnung, streamt via SSE
  • AI-Analyse: Transkript-Segmente werden durch AI-Modell (GPT-4o-mini / Claude) analysiert
  • Voice Response: TTS-Audio wird über den Mikrofon-Kanal ins Meeting gespielt
  • Chat Response: Bot kann Chat-Nachrichten ins Meeting schreiben
  • Multi-Session: Mehrere Bot-Instanzen parallel in verschiedenen Meetings

Use Cases

UC Beschreibung
AI Meeting Assistant Bot nimmt teil, hört zu, antwortet auf Ansprache ("Hey Nyla, ...")
Live Transcription Echtzeit-Transkript-Stream für Teilnehmer ausserhalb des Meetings
Meeting Summary AI-generierte Zusammenfassung nach Meeting-Ende
Multi-Bot Mehrere parallele Sessions in verschiedenen Meetings
Director Prompts Operator gibt dem laufenden Bot private Regieanweisungen (One-Shot oder Persistent), Antwort wird ins Meeting eingespielt
Hybrid Agent Escalation SPEECH_TEAMS-Pfad kann komplexe Anfragen via needsAgent=true an den vollen Agent (agentService.runAgent) eskalieren

Integration mit Gateway

Der Gateway (Feature teamsbot) verwaltet Sessions und stellt die AI-Pipeline bereit:

  • Session-Lifecycle: erstellen, starten, stoppen
  • WebSocket-Verbindung pro Session
  • AI-Analyse der Transkript-Segmente via serviceAi
  • TTS-Generierung für Voice-Responses

Schlüssel-Dateien

Datei / Bereich Rolle
gateway/modules/features/teamsbot/ Gateway-seitiges Feature-Modul
service-teams-browser-bot/ Eigenständiger Bot-Service (separates Repository)

Regeln / Invarianten

  • Bot tritt als regulärer Web-Teilnehmer bei (Browser-Automation), nicht via Graph Communications SDK
  • Jede Session läuft in einer eigenen Browser-Instanz (Isolation)
  • Authentifizierter Join (mit Microsoft-Account) oder Anonymous Guest -- je nach Konfiguration
  • Gateway ist die einzige Schnittstelle für AI-Aufrufe und TTS -- der Bot-Service selbst hat keine AI-Logik

Hybrid-Routing: SPEECH_TEAMS + Agent

Der Teamsbot läuft auf zwei kooperierenden Pfaden:

flowchart LR
    Audio["Meeting Audio"] --> STT["STT"]
    STT --> ST["SPEECH_TEAMS<br/>(fast, low-latency)"]
    ST -->|shouldRespond=true| TTS["TTS + Chat"]
    ST -->|needsAgent=true| Agent["agentService.runAgent<br/>(toolSet=core, web=on,<br/>maxRounds=5, maxCostCHF=0.10)"]
    Agent -->|FINAL text| TTS
    UI["Operator UI<br/>(Regie-Panel + UDB)"] -->|POST directorPrompt| Route["routeFeatureTeamsbot"]
    Route -->|submitDirectorPrompt| Svc["TeamsbotService<br/>(_activeServices)"]
    Svc -->|asyncio.create_task| Agent
    TTS --> Meeting
    Svc -->|SSE 'directorPrompt'| UI
  • SPEECH_TEAMS bleibt der Default-Pfad mit niedrigster Latenz. Der dazugehörige System-Prompt erlaubt dem Modell explizit, needsAgent=true + agentReason zu setzen, wenn die Anfrage Web-Recherche, Mail oder Multi-Step-Tools erfordert.
  • Director Prompts umgehen SPEECH_TEAMS komplett und feuern direkt einen runAgent-Lauf, dessen FINAL-Event-Text wieder über die bestehenden TTS-/Chat-Kanäle ins Meeting geliefert wird.

Director Prompts (private Operator-Anweisungen)

Operator-Prompts sind privat (nur per SSE an den Session-Owner sichtbar) und werden in PostgreSQL gespeichert (poweron_teamsbot.TeamsbotDirectorPrompt).

Modus Verhalten
oneShot Einmaliger Agent-Lauf, danach Status consumed
persistent Agent-Lauf wird ausgeführt und der Text wird als OPERATOR_DIRECTIVES-Block in jeden folgenden SPEECH_TEAMS-Trigger eingemischt, bis der Operator den Prompt löscht
Lifecycle-Status Bedeutung
queued Eingereicht, Agent noch nicht gestartet
running Agent läuft
succeeded Agent fertig, persistent bleibt aktiv
consumed One-Shot abgeschlossen oder persistent gelöscht
failed Agent-Lauf fehlgeschlagen, persistent wird automatisch aus aktiven Direktiven entfernt

Persistenz beim Reconnect: Bei jedem WebSocket-Reconnect ruft der Service interface.getActivePersistentPrompts(sessionId) auf und füllt _activePersistentPrompts neu, damit Direktiven Network-Drops überleben.

Limits: DIRECTOR_PROMPT_TEXT_LIMIT = 8000 Zeichen, DIRECTOR_PROMPT_FILE_LIMIT = 10 UDB-Dateien (Pflicht-Prüfung in der Route, validiert auch von TeamsbotDirectorPromptCreateRequest).

RBAC: Routes prüfen _validateInstanceAccess + _validateSessionOwnership. Ein Nicht-Owner sieht 404, niemals 403, um die Existenz der Session nicht preiszugeben.

Rate-Limit: 30/minute pro Operator (slowapi).

Schicht-Trennung (Plan #5 abgeschlossen 2026-04-24)

Verantwortung Datei
Persistenz + Lifecycle interfaceFeatureTeamsbot.py (createDirectorPrompt, getActivePersistentPrompts, updateDirectorPrompt, deleteDirectorPrompt)
Orchestrierung + Agent-Lauf + SSE service.py (submitDirectorPrompt, _processDirectorPrompt, _runAgentForMeeting, _buildPersistentDirectorContext, removePersistentPrompt)
HTTP + RBAC + Limits routeFeatureTeamsbot.py (POST/GET/DELETE /sessions/{id}/directorPrompts)
Frontend Regie-Panel + UDB-Sidebar + SSE-Listener frontend_nyla/src/pages/views/teamsbot/TeamsbotSessionView.tsx + Teamsbot.module.css
Frontend API-Wrapper frontend_nyla/src/api/teamsbotApi.ts (submitDirectorPrompt, listDirectorPrompts, deleteDirectorPrompt)
Tests gateway/tests/unit/teamsbot/test_directorPrompts.py (26 Tests, AC 5 + 6 abgedeckt; AC 14 manuell live)