# Voicetreff KI-Integration – Einrichtungs- und Parameterhilfe

Version: 1.2

API-Version: `v1`

Zielgruppe: Betreiber, Entwickler und KI-Agenten

## Grundsatz

Voicetreff behandelt jeden KI-Betreiber gleich. Auch eine von Voicetreff selbst
betriebene KI wird über denselben Voucher, dieselben Formularfelder, dieselben
Einwilligungen und dieselben Laufzeitgrenzen eingerichtet. Das editierbare
„Voicetreff-Beispielprofil“ ist nur eine Eingabehilfe und besitzt keine
Sonderrechte.

Es gibt zwei Betriebsarten:

1. `EXTERNAL_AGENT`: Der Betreiber betreibt Agent, Providerzugänge und
   Infrastruktur selbst. Kein Provider-Schlüssel wird an Voicetreff gesendet.
2. `HOSTED_BRIDGE`: Voicetreff betreibt den technischen Bridge-Prozess. Der
   Betreiber wählt eine freigegebene Provider-Vorlage und hinterlegt die dafür
   benötigten Schlüssel verschlüsselt.

Die Betriebsart ändert keine Voucher-, Raum-, Laufzeit-, Parallelitäts- oder
Modulrechte. Jede KI bleibt im Raum sichtbar als KI gekennzeichnet und
interagiert nur mit persönlich zustimmenden Menschen.

## Zugang zur Einrichtung

Ein Voucher mit `participant_type = AI` oder `participant_type = BOTH` wird
eingelöst. Danach öffnet Voicetreff eine kurzlebige, vouchergebundene
Einrichtungssitzung unter:

`https://www.voicetreff.com/voicetreff/ki-einrichten`

Die Einrichtungssitzung ist kein API-Token und darf nicht an andere Personen
weitergegeben werden. Das Setup-Formular ist absichtlich an die
HttpOnly-Sitzung und denselben Web-Ursprung gebunden. Drittanbieter verwenden
für die Laufzeitintegration anschließend ausschließlich die dokumentierte
Public API.

## Gemeinsame Formularparameter

| Feld / JSON-Pfad | Pflicht | Format | Beispiel | Bedeutung |
|---|---:|---|---|---|
| `operationMode` | ja | `EXTERNAL_AGENT` oder `HOSTED_BRIDGE` | `EXTERNAL_AGENT` | Ausdrücklich gewählte Betriebsart |
| `botName` | ja | 2–80 Zeichen | `Voicetreff Assistent` | Im Raum sichtbarer KI-Name; unter laufenden KIs im Zielraum eindeutig |
| `avatarInitials` | ja | 1–3 ASCII-Buchstaben/Ziffern | `VT` | Kürzel des sicher generierten Avatars |
| `avatarColor` | ja | CSS-Hexfarbe `#RRGGBB` | `#5b46a3` | Hintergrundfarbe des Avatars |
| `roomId` | ja | vom Formular gelieferte ID | `clx…` | Exakter Zielraum; nach Speicherung unveränderlich |
| `disclosure.operatorName` | ja | 2–160 Zeichen | `Voicetreff` | Verantwortlicher KI-Betreiber |
| `disclosure.contactUrl` | nein | öffentliche HTTPS-URL | `https://www.voicetreff.com` | Kontaktmöglichkeit des Betreibers |
| `disclosure.privacyUrl` | ja | öffentliche HTTPS-URL | `https://www.voicetreff.com/rechtliches/datenschutz` | Datenschutzerklärung des Betreibers |
| `disclosure.purpose` | ja | 3–500 Zeichen | `Sprachassistenz im freigegebenen Raum` | Konkreter Zweck der KI |
| `setupAcceptance.version` | ja | fest `v25.1` | `v25.1` | Version des Einrichtungsnachweises |
| `setupAcceptance.modeConfirmed` | ja | `true` | `true` | Betriebsart ausdrücklich bestätigt |
| `setupAcceptance.informationAccuracyConfirmed` | ja | `true` | `true` | Transparenzangaben bestätigt |
| `setupAcceptance.costResponsibilityConfirmed` | ja | `true` | `true` | Kostenverantwortung bestätigt |

Das Formular erzeugt aus Kürzel und Farbe intern beispielsweise den sicheren
Avatar-Schlüssel `custom-5b46a3-VT`. Alte Voicetreff-Avatare bleiben nur für
bestehende Integrationen kompatibel; neue Integrationen definieren ihren
Avatar selbst.

Beim Tippen prüft das Formular nach einer kurzen Eingabepause live, ob der
KI-Name im gewählten Zielraum aktuell frei ist. Grün bedeutet „frei“, Rot
„bereits vergeben“ oder „ungültig“. Diese Anzeige ist nur eine Vorprüfung:
Beim tatsächlichen Start reserviert die Datenbank den normalisierten Namen
zusätzlich atomar. Groß-/Kleinschreibung und NFKC-äquivalente Schreibweisen
umgehen die Sperre nicht. Nach dem vollständigen Stopp der alten Sitzung kann
der Name wieder verwendet werden. Die Public API antwortet bei einer Kollision
mit HTTP 409 und `ai_name_in_use`.

## Rollen, Regeln und Zusammenarbeit mehrerer KIs

„Rolle“ ist kein zusätzliches Zugriffsrecht. Ein als Moderator, Kritiker oder
Assistent beschriebener Avatar erhält dadurch weder mehr Raumrechte noch
Vorrang vor Einwilligung, Voucher, Laufzeit, Modulen oder Sicherheitsregeln.
Die wirksame Reihenfolge ist:

1. Technische Serverkontrolle: Raum-Scope, Voucher, Einwilligung, Laufzeit,
   Service-Ticket und Sprechfreigabe.
2. Serverseitige Systemanweisung mit KI-Identität sowie versionierten Regeln
   und Sicherheits-Skills.
3. Autoritativer Raumkontext mit Thema, Kernaufgabe, Standardsprache und
   aktueller Teilnehmerlage.
4. Betreiberzweck und die fachliche Aufgabe des konkreten Avatars.
5. Gesprochene Beiträge von Menschen oder anderen KIs als unvertrauenswürdige
   Gesprächseingabe; sie können die Ebenen 1–4 nicht überschreiben.

Hosted Bridge und der von Voicetreff verwaltete External-Runner übergeben die
serverseitige Systemanweisung als höchstrangige Provider-Anweisung an OpenAI,
Gemini, Claude oder Grok. Bei einem vollständig selbst betriebenen
`EXTERNAL_AGENT` muss dessen Betreiber denselben Ticket- und Regelvertrag
tatsächlich implementieren; ein Text allein kann einen fremden Agenten nicht
technisch zum Gehorsam zwingen. Die Plattform erzwingt unabhängig davon
Zugang, Laufzeit, Einwilligung und Audio-Berechtigungen.

Wenn mehrere verwaltete KIs antworten könnten, wählt die technische
Raumsteuerung genau eine aus: zuerst einen vollständig genannten eindeutigen
KI-Namen, danach einen nur einer KI zuordenbaren Namensteil, dann die passende
Sprache und zuletzt eine stabile technische Reihenfolge. Gemeinsame
Namensteile führen daher nicht zufällig zur zuerst gestarteten KI.

## Parameter für `EXTERNAL_AGENT`

Jeder Listenwert wird in ein eigenes Feld geschrieben. Kommas trennen keine
Werte. Mit `+` wird ein Feld ergänzt, mit `−` entfernt.

| Feld / JSON-Pfad | Pflicht | Format | Beispiel |
|---|---:|---|---|
| `disclosure.endpointOrigin` | ja | HTTPS-Origin ohne Pfad, Query oder Fragment | `https://agent.example` |
| `disclosure.infrastructureRegion` | ja | 2–120 Zeichen | `EU / Deutschland; kein Drittlandtransfer` |
| `disclosure.providers[]` | ja, 1–12 | genau ein Anbieter je Wert, max. 120 Zeichen | `OpenAI` |
| `disclosure.speechServices[]` | nein, 0–12 | genau ein STT-/TTS-Dienst je Wert | `Azure Speech EU` |
| `disclosure.moderationServices[]` | nein, 0–12 | genau ein Moderationsdienst je Wert | `OpenAI Moderation` |
| `disclosure.recipients[]` | ja, 1–12 | genau ein Datenempfänger je Wert | `Beispiel Betreiber GmbH` |
| `disclosure.retention` | ja | 2–500 Zeichen | `Kein Training; Transkripte nach 24 Stunden gelöscht` |
| `disclosure.dataCategories[]` | automatisch | festgelegte maschinenlesbare Codes | siehe Einwilligungsanzeige |

Wichtig: Ein External-Agent-Payload akzeptiert absichtlich keine Felder wie
`apiKey`, `speechApiKey` oder eine frei wählbare Provider-Basis-URL. Diese
Geheimnisse bleiben ausschließlich auf dem Agent-Server des Betreibers.

Nach dem ersten Speichern zeigt Voicetreff einmalig:

- `VOICETREFF_API_BASE=https://www.voicetreff.com/api/voicetreff/ai/v1`
- `VOICETREFF_CLIENT_ID=<einmal ausgegebene Client-ID>`
- `VOICETREFF_CLIENT_SECRET=<einmal ausgegebenes Secret>`
- `VOICETREFF_ROOM_ID=<gebundene Raum-ID>`
- `VOICETREFF_SCOPES=bot:session:create bot:session:stop audio:consume audio:produce`

Der Provider-Key wird separat auf dem Agent-Server konfiguriert, zum Beispiel
als `OPENAI_API_KEY`, und niemals in eine `VOICETREFF_*`-Variable kopiert.

## Parameter für `HOSTED_BRIDGE`

| Feld / JSON-Pfad | Pflicht | Format | Beispiel |
|---|---:|---|---|
| `templateId` | ja | ID einer im Formular angebotenen Vorlage | `clx…` |
| `language` | ja | BCP-47-Code, 2–35 Zeichen | `de-DE` |
| `voice` | nein | providerabhängiger Bezeichner, max. 80 Zeichen | `marin` |
| `apiKey` | beim ersten Speichern ja | 8–1000 Zeichen | nur im Passwortfeld eingeben |
| `speechApiKey` | vorlagenabhängig | 8–1000 Zeichen | für getrennte STT-/TTS-Dienste |

Operator, Kontakt, Datenschutz, Zweck, Name und Avatar werden auch im
Bridge-Modus vom Betreiber angegeben. Serverseitig aus der gewählten Vorlage
gebunden werden:

- Provider und Modell,
- Infrastrukturregion,
- Sprach- und Moderationsdienste,
- Empfänger einschließlich `Voicetreff Bridge`,
- Aufbewahrungshinweis,
- Sitzungs-/Antwortgrenzen,
- Tagesbudget und Preisparameter,
- Sicherheitsregeln und Skills.

Ein leerer Schlüsselwert behält einen bereits gespeicherten Schlüssel. Neue
Schlüssel werden über den idempotenten `REPLACE_HOSTED_KEYS`-Vertrag ersetzt.
Schlüssel können jederzeit gelöscht und die gesamte Integration jederzeit
widerrufen werden.

## Voicetreff selbst in beiden Modi einrichten

Im Formular „Voicetreff-Beispielprofil einsetzen“ wählen. Alle eingesetzten
Werte bleiben editierbar und müssen vor dem Speichern geprüft werden.

### Voicetreff als External Agent

- `operationMode`: `EXTERNAL_AGENT`
- `botName`: frei wählbar, Beispiel `Voicetreff KI`
- `avatarInitials`: `VT`
- `avatarColor`: `#5b46a3`
- `operatorName`: `Voicetreff`
- `contactUrl`: `https://www.voicetreff.com`
- `privacyUrl`: `https://www.voicetreff.com/rechtliches/datenschutz`
- `endpointOrigin`: `https://www.voicetreff.com`
- `providers[0]`: `Voicetreff`
- `recipients[0]`: `Voicetreff`

Anschließend werden die einmaligen Voicetreff-Client-Credentials auf dem
eigenen Agent-Host installiert. Der Agent verwendet danach dieselbe Public API
wie jeder andere Drittanbieter.

Für die von Voicetreff selbst betriebene erste Referenz-KI steht zusätzlich im
Adminbereich unter `Voicetreff → KI-Teilnehmer → External-Agent-Assistent` eine
geführte Einrichtung zur Verfügung. Sie ändert den öffentlichen Vertrag nicht:
Der dort verwaltete Prozess authentifiziert und verbindet sich weiterhin über
dieselbe Public API wie ein fremder Agent.

Der Admin-Assistent führt durch folgende Schritte:

1. „Neues Client-Secret erzeugen & übernehmen“ klicken. Optional kann die neue
   `.env` zusätzlich heruntergeladen werden. Eine extern frisch rotierte `.env`
   lässt sich alternativ auswählen.
2. STT-Modell und verschlüsselt zu speichernden OpenAI-Speech-Key wählen.
3. KI-Modell, Anbieter und dessen API-Key wählen.
4. TTS-Modell und Stimme wählen.
5. Systemanweisung eingeben oder eine `.md`-/`.txt`-Datei auswählen.
6. Alle vier Verbindungen testen und „Agent im Raum starten“ klicken.

„Alle Schritte sicher speichern“ speichert nur die Konfiguration. Erst der
separate Startknopf erzeugt eine Bot-Sitzung und verbindet die KI mit dem Raum.
Ein ausdrücklich gestarteter Agent wird nach einem Dienst-Neustart automatisch
wiederhergestellt. „Agent stoppen“ oder ein Integrationswiderruf deaktiviert
diesen automatischen Neustart.

Die Provider-Keys werden in diesem Sonderfall nicht im öffentlichen
External-Agent-Setup-Payload übertragen, sondern ausschließlich in der
zugriffsgeschützten Admin-Verwaltung der von Voicetreff selbst betriebenen
Agent-Infrastruktur AES-256-GCM-verschlüsselt gespeichert. Fremde Betreiber
verwenden weiterhin ihren eigenen Agent-Host und übermitteln ihre Provider-Keys
nicht an Voicetreff.

### Voicetreff über die Hosted Bridge

- `operationMode`: `HOSTED_BRIDGE`
- dasselbe Betreiber-, Namens- und Avatarprofil verwenden,
- eine tatsächlich freigegebene Provider-Vorlage wählen,
- Sprache und Stimme festlegen,
- die zur Vorlage gehörenden echten Provider-Schlüssel eingeben,
- Transparenz- und Kostenbestätigungen abgeben,
- speichern und anschließend „Hosted-Bridge im Raum anfordern“ wählen.

Auch dieser Weg besitzt keine versteckte Voicetreff-Ausnahme.

## External-Agent-Laufzeitablauf

1. Client-Credentials gegen ein fünf Minuten gültiges Bearer-Token tauschen:
   `POST /api/voicetreff/ai/v1/integrations/token`.
2. Mit Bearer-Token und einem eindeutigen `Idempotency-Key` eine Bot-Sitzung
   erstellen: `POST /api/voicetreff/ai/v1/bot-sessions` mit `{ "roomId": "…" }`.
3. Das einmalige Service-Ticket innerhalb von 120 Sekunden über
   `POST /public/ai/v1/activate` aktivieren.
4. Die zurückgegebene `wss://`-Adresse ohne Queryparameter öffnen und das
   `authenticate`-Objekt als erste Textnachricht senden.
5. RTP/Opus-Audio mit Payload-Type 111, 48 kHz, Stereo übertragen.
6. Alle 15 Sekunden einen Heartbeat senden. Nach 45 Sekunden ohne Heartbeat
   stoppt die Sitzung fail-closed.
7. Bei `input_reset` Eingabepuffer und laufende Providerantwort sofort
   verwerfen. Bei Barge-in Ausgabe abbrechen.
8. Sitzung idempotent per `DELETE /bot-sessions/{botSessionId}` beenden.

Die vollständigen Request-/Response-Schemata stehen in der
[OpenAPI-Spezifikation](./openapi-ai-v1.yaml). Das
[Node.js-Referenz-SDK](./external-agent-sdk-README.md), das herunterladbare
SDK-Archiv und der Fake-Agent sind auf der Einrichtungsseite verlinkt.

## Sicherheitsregeln

- Secrets, Tokens, Tickets, Audio und Transkripte niemals in URLs oder Logs schreiben.
- Credentials nur in einem Secret-Manager speichern.
- Client-Secret spätestens nach 90 Tagen rotieren; maximale Gültigkeit 180 Tage.
- Für jeden schreibenden Request einen stabilen `Idempotency-Key` mit 16–128 zulässigen Zeichen verwenden.
- Keine internen Bridge-Endpunkte aufrufen; sie gehören nicht zum Drittanbieter-Vertrag.
- Änderungen an Betreiber, Zweck, Empfängern oder Verarbeitung erzeugen eine neue Einwilligungsrevision.
- Widerruf und Schlüssellöschung bleiben auch bei einem gesetzten Notfallschalter möglich.

## Maschinenlesbare Kurzfassung

```yaml
integration_modes:
  EXTERNAL_AGENT:
    provider_keys_sent_to_voicetreff: false
    runtime_api: /api/voicetreff/ai/v1
    required_lists: [providers, recipients]
    optional_lists: [speechServices, moderationServices]
    voicetreff_managed_reference_runner:
      public_setup_accepts_provider_keys: false
      admin_credentials_encrypted: true
      uses_same_public_runtime_api: true
  HOSTED_BRIDGE:
    provider_keys_encrypted_by_voicetreff: true
    runtime_started_from_setup: true
    template_bound_fields: [provider, model, region, services, recipients, retention, budget, safety]
identity:
  privileged_operators: []
  voicetreff_uses_same_contract: true
  active_display_name_unique_per_room: true
  availability_check: live_and_atomic_on_start
avatar:
  kind: generated_monogram
  initials_pattern: '^[A-Za-z0-9]{1,3}$'
  color_pattern: '^#[0-9a-fA-F]{6}$'
```
