Streaming mit einem eigenen SSE-Parser
Chat-Antworten werden über Server-Sent Events gestreamt – mit einem eigens entwickelten Parser, der reale Netzwerkbedingungen berücksichtigt. Eine dedizierte SSEStreamError-Klasse unterscheidet Server-Fehler von JSON-Parse-Fehlern und verhindert das Catch-all-Anti-Pattern, bei dem legitime Fehlerantworten stillschweigend verschluckt werden. Die SSELineBuffer-Klasse behandelt TCP-Paketgrenzentrennung – wenn eine einzelne SSE-Zeile über mehrere reader.read()-Aufrufe hinweg ankommt, setzt der Buffer sie vor dem Parsing wieder zusammen.
Im SSE-Stream eingebettete Server-Fehler (z. B. {"error": "rate limit exceeded"}) erscheinen sofort in der UI, anstatt leere Chat-Bubbles zu erzeugen. Sowohl String- als auch Object-Fehlerformate werden unterstützt.
Zweiphasiges Laden
Der Ladeindikator arbeitet in zwei klar getrennten Phasen. Phase A überbrückt die Zeitspanne zwischen dem Absenden durch den User und dem Anlegen der Assistant-Nachricht durch den Server – unterhalb der User-Nachricht erscheint ein eigenständiger Ladeblock. Phase B beginnt, sobald die Assistant-Nachricht existiert und das Streaming startet: Der Indikator wechselt in einen Inline-Streaming-Indikator innerhalb der Nachrichtenblase. Das verhindert den störenden Aufblitz einer leeren Bubble, den einfache Lader ohne Phasentrennung verursachen.
Audio-Eingabe
Die Sprache-zu-Text-Eingabe nutzt die MediaRecorder API, um Audio direkt im Browser aufzuzeichnen. Aufnahmen werden serverseitig transkribiert und in das Chat-Eingabefeld eingefügt. Die Implementierung verwendet einen Session-Counter (monotoner useRef-Integer) statt einer Boolean-Ref für das asynchrone Abbrechen – das verhindert Race Conditions, wenn sich Aufnahme-Sessions überschneiden und ein veraltetes Promise aus Session N fälschlicherweise in Session N+1 weiterläuft.