wiki/c-work/4-done/2026-04-teamsbot-director-prompts.md
ValueOn AG d4095db4f2 fixes
2026-04-25 01:13:24 +02:00

154 lines
8.3 KiB
Markdown

<!-- status: done -->
<!-- started: 2026-04-23 -->
<!-- completed: 2026-04-24 -->
<!-- component: gateway, frontend-nyla, teams-bot -->
<!--
Vollstaendig umgesetzt: Datamodel, Interface-CRUD, _activeServices-Registry,
submit/_processDirectorPrompt + _runAgentForMeeting, Reconnect-Persistenz,
Hybrid-Routing (needsAgent), SystemPrompt mit Eskalations-Regeln, Routes
POST/GET/DELETE mit RBAC + Limits + Rate-Limit, Frontend-API + SSE-Listener
+ UDB-Sidebar + Regie-Panel + CSS. 26 Backend-Unit-Tests gruen
(gateway/tests/unit/teamsbot/test_directorPrompts.py). AC 5 + 6 abgedeckt;
AC 1-4 sind manuelle Live-Meeting-Tests.
b-reference: teams-bot/architecture.md (Hybrid + Director Prompts) und
gateway/ai-agent.md (Teamsbot-Integration, kein eigenes Toolset) sind
aktualisiert; TOPICS.md gepflegt.
-->
# Teamsbot Regieanweisungen (Director Prompts)
## Beschreibung und Kontext
Der Teamsbot laeuft heute auf einem hochspezialisierten, schnellen Pfad
(`OperationTypeEnum.SPEECH_TEAMS`), der reaktiv auf Sprache reagiert.
Der Operator soll dem Bot waehrend des Meetings *privat* Anweisungen geben
koennen ("Recherchiere das gerade diskutierte Thema und gib eine Empfehlung",
"Lies die Datei XY vor", "Schreib das ins Chat"). Diese **Regieanweisungen**
sind fuer die anderen Teilnehmer unsichtbar und triggern den Bot sofort,
unabhaengig von Cooldowns oder Sprach-Triggern.
Long-term-clean: Voller Agent-Pfad mit RAG, Datenschnittstellen, Toolboxen.
## Fokus und kritische Details
- **Hybrid-Routing**: `SPEECH_TEAMS` bleibt der schnelle Default-Pfad.
Der Agent (`agentService.runAgent`) wird nur fuer (a) Director Prompts und
(b) `SPEECH_TEAMS`-Eskalation (`needsAgent=true`) verwendet.
- **Privacy**: Director-Prompts werden in der DB gespeichert und ueber SSE
ausschliesslich an den Operator (Eigentuemer der Session) ausgeliefert.
- **Kein neues Teamsbot-Toolset**: Der Agent verwendet bestehende Core-Tools
(`webSearch`, `readUrl`, `sendMail`, `renderDocument`, `requestToolbox`,
Datenschnittstellen-Tools etc.). Sein finaler `FINAL`-Event-Text wird wie
eine `SPEECH_TEAMS`-Antwort ueber TTS+Chat ans Meeting ausgeliefert.
- **Persistenz**: Persistente Director-Prompts werden bei jedem Trigger
(SPEECH_TEAMS und neuer Director-Prompt) als zusaetzlicher Kontext in den
System-Prompt gemischt, bis der Operator sie loescht.
- **Service-Registry**: Damit eine HTTP-Route auf die laufende WS-Session
zugreifen kann, registriert `handleBotWebSocket` den `TeamsbotService` mit
`websocket` + `voiceInterface` modul-weit.
## Ziel und Nicht-Ziele
- Ziel: Operator kann private Text-Prompts (mit optional UDB-Files) an den
laufenden Bot senden; Bot fuehrt Agent-Run aus, antwortet ins Meeting per
TTS/Chat und kann Tools (Web, Mail, SharePoint, ...) nutzen.
- Ziel: SPEECH_TEAMS kann selbststaendig signalisieren `needsAgent=true`,
damit komplexe Spoken-Requests (z. B. "recherchier das im Internet") den
Agent triggern, statt nur eine Floskel zurueckzugeben.
- Nicht-Ziel: Eigene Teamsbot-spezifische Tools fuer den Agent (sendChat,
readAloud) — diese bleiben im SPEECH_TEAMS-Pfad als `commands`. Der Agent
spricht nur ueber seinen Final-Text, der vom Service ausgeliefert wird.
- Nicht-Ziel: PDF-Anhang in Teams-Chat (Browser-Bot-Limit). Stattdessen wird
der vom Agent generierte Link gepostet.
## Betroffene Module
- Gateway: `modules/features/teamsbot/datamodelTeamsbot.py`,
`interfaceFeatureTeamsbot.py`, `service.py`, `routeFeatureTeamsbot.py`,
`modules/serviceCenter/services/serviceAi/mainServiceAi.py`
- Frontend: `src/api/teamsbotApi.ts`, `src/pages/views/teamsbot/TeamsbotSessionView.tsx`,
`src/pages/views/teamsbot/Teamsbot.module.css`
- DB-Migration: ja (neue Tabelle `teamsbotDirectorPrompts` via `registerDatabase`/Auto-Migrate)
- Andere: `service-teams-browser-bot` — keine Aenderungen (Agent nutzt
bestehende WS-Commands `sendChatMessage`, `playAudio`).
## Architektur
```mermaid
flowchart LR
UI["Operator UI (Regie-Panel + UDB)"] -- POST directorPrompt --> Route["routeFeatureTeamsbot"]
Route -- submitDirectorPrompt --> Svc["TeamsbotService (active)"]
Svc -- runAgent --> Agent["agentService.runAgent (toolSet=core, web aktiv, maxRounds=5)"]
Agent -- FINAL text --> Svc
Svc -- TTS+sendChatMessage --> WS["Browser Bot (WS)"]
WS -- audio/chat --> Meeting
Audio["Meeting Audio"] --> STT["STT"]
STT --> SpeechTeams["SPEECH_TEAMS (fast)"]
SpeechTeams -- needsAgent? --> Agent
SpeechTeams -- direct text/commands --> Svc
```
## Entscheidungen
| Datum | Entscheidung | Begruendung |
|------------|-------------------------------------------------|-------------|
| 2026-04-23 | Hybrid-Routing SPEECH_TEAMS + Agent | Latenz fuer Reaktivitaet, Funktionalitaet fuer Komplexes |
| 2026-04-23 | Kein eigenes Teamsbot-Toolset im Agent | Agent-Final-Text wird wie SPEECH_TEAMS-Text ausgeliefert; vermeidet Tool-Duplikation |
| 2026-04-23 | `web`-Toolbox als Default + `requestToolbox` aktiv | Recherche ist Standard, andere Toolboxen on-demand |
| 2026-04-23 | `maxRounds=5`, `maxCostCHF=0.10` | Live-Performance + Kosten-Cap |
| 2026-04-23 | UDB-Sidebar wie in CommcoachDossierView | Bestehendes Muster, Files via fileIds |
## Umsetzungs-Checkliste
- [x] Datamodel `TeamsbotDirectorPrompt` + `SpeechTeamsResponse.needsAgent`
- [x] Interface CRUD + DB-Registrierung
- [x] `_activeServices` Registry + WS/Voice auf Instanz
- [x] `submitDirectorPrompt` + `_processDirectorPrompt` (Agent-Call + Delivery)
- [x] Persistente Prompts beim Reconnect aus DB laden
- [x] Hybrid: `_analyzeAndRespond` triggert Agent bei `needsAgent=true`
- [x] `_buildSpeechTeamsSystemPrompt` um `needsAgent`-Felder erweitern
- [x] Routes `POST/GET/DELETE /sessions/{id}/directorPrompts`
- [x] Frontend API + SSE-Event-Type
- [x] Frontend UDB-Sidebar + Regie-Panel + CSS
- [x] RBAC: nur Session-Owner darf submitten/listen/loeschen (`_validateInstanceAccess` + `_validateSessionOwnership`)
- [x] Neutralisierung: Director-Prompt-Text geht durch Standard-AiService -> automatisch im Scope
- [x] Navigation: keine neue Route, nur Panel in TeamsbotSessionView
- [x] Billing: laeuft ueber `agentService.runAgent` (Standard-Billing) und `aiService.callAi` (SPEECH_TEAMS Billing); kein neuer Pfad
- [x] Unit-Tests (26 Tests, T5 + AC 5 + AC 6 abgedeckt)
- [x] b-reference + TOPICS.md aktualisiert
## Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio |
|---|-----------------------------|------|
| 1 | Given laufendes Meeting, When Operator sendet One-Shot Prompt "Was ist die Hauptstadt von Frankreich?", Then Bot antwortet im Meeting per Voice "Paris" innerhalb 10s | must |
| 2 | Given laufendes Meeting + UDB-File ausgewaehlt, When Operator sendet Prompt "Fasse das ausgewaehlte Dokument zusammen", Then Bot liest Datei via `readFile`, fasst zusammen, antwortet Voice+Chat | must |
| 3 | Given laufendes Meeting, When Operator sendet Persistent-Prompt "Antworte immer in Englisch", Then jede folgende SPEECH_TEAMS-Antwort ist auf Englisch, bis Operator den Prompt loescht | must |
| 4 | Given Sprecher sagt "Nyla, recherchier was im Internet ueber SBB Schweiz", When SPEECH_TEAMS verarbeitet, Then `needsAgent=true` und Agent uebernimmt mit `webSearch`, antwortet ueber TTS | must |
| 5 | Given Operator sendet Prompt mit fileIds=[A,B,C], When Limit DIRECTOR_PROMPT_FILE_LIMIT (10) ueberschritten oder Text > 8000 Zeichen, Then Route gibt 400 zurueck | must |
| 6 | Given anderer User (nicht Owner) ruft GET /directorPrompts auf, Then 404 | must |
## Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad | Status |
|----|----|-----|---------------|-----------|--------|
| T1 | 1 | manual e2e | nein | live meeting | pending (manual) |
| T2 | 2 | manual e2e | nein | live meeting | pending (manual) |
| T3 | 3 | manual e2e | nein | live meeting | pending (manual) |
| T4 | 4 | manual e2e | nein | live meeting | pending (manual) |
| T5 | 5,6| api unit | ja | gateway/tests/unit/teamsbot/test_directorPrompts.py | done (26 Tests) |
## Links
- PR: TBD
- Issue: TBD
## Abschluss
- [x] `wiki/b-reference/teams-bot/architecture.md` (Director Prompts + Hybrid + Tool-Set)
- [x] `wiki/b-reference/gateway/ai-agent.md` (kein neues Teamsbot-Toolset, Hybrid-Routing)
- [x] `wiki/TOPICS.md` (Teams-Bot-Eintrag um Director Prompts ergaenzt + neuer Aktive-Arbeiten-Eintrag)
- [x] Diesen Plan nach `4-done/` verschieben