feat: Max-Aufnahmedauer konfigurierbar + Barge-In gibt aria-core Kontext

Max-Aufnahme:
Default rauf von 2 auf 5 Minuten, in den App-Settings konfigurierbar
zwischen 1 und 30 Minuten (loadMaxRecordingMs aus AsyncStorage,
Storage-Key aria_max_recording_sec). Notbremse-Verhalten bleibt:
nach Ablauf wird die Aufnahme automatisch beendet und gesendet.

Barge-In Kontext:
Wenn der User waehrend ARIA noch redet/arbeitet eine neue Sprach-
oder Text-Nachricht sendet, geht jetzt ein 'interrupted: true' Flag
mit. Bridge praefixed den Text fuer aria-core dann mit:

  "[Hinweis: Stefan hat dich gerade unterbrochen waehrend du noch
  gesprochen oder gearbeitet hast. Folgendes ist eine Korrektur,
  Ergaenzung oder ein Themenwechsel zu deiner letzten Antwort.]"

So weiss ARIA dass die neue Message KEINE eigenstaendige Folgefrage
ist sondern auf den abgebrochenen Run bezogen. Der User sieht in
seinem Chat nur den reinen Text — der Hint geht nur an aria-core.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-06 21:58:11 +02:00
parent 406f4cb3cc
commit 31ff20c846
4 changed files with 111 additions and 18 deletions
+23 -5
View File
@@ -145,7 +145,24 @@ async function loadVadSilenceMs(): Promise<number> {
// Max-Dauer einer Aufnahme (Notbremse gegen Runaway-Loops). Auf 2 Minuten
// hochgezogen damit auch laengere Erklaerungen durchgehen.
const MAX_RECORDING_MS = 120000;
// Default 5 Minuten — konfigurierbar in den App-Settings (1-30 Minuten).
export const MAX_RECORDING_DEFAULT_SEC = 300;
export const MAX_RECORDING_MIN_SEC = 60;
export const MAX_RECORDING_MAX_SEC = 1800;
export const MAX_RECORDING_STORAGE_KEY = 'aria_max_recording_sec';
export async function loadMaxRecordingMs(): Promise<number> {
try {
const raw = await AsyncStorage.getItem(MAX_RECORDING_STORAGE_KEY);
if (raw != null) {
const n = parseFloat(raw);
if (isFinite(n) && n >= MAX_RECORDING_MIN_SEC && n <= MAX_RECORDING_MAX_SEC) {
return Math.round(n * 1000);
}
}
} catch {}
return MAX_RECORDING_DEFAULT_SEC * 1000;
}
// Pre-Roll: Wie lange Audio im AudioTrack-Buffer liegt bevor play() startet.
// Einstellbar via Diagnostic/Settings (Key: aria_tts_preroll_sec).
@@ -440,18 +457,19 @@ class AudioService {
};
if (autoStop) {
const vadSilenceMs = await loadVadSilenceMs();
const maxRecordingMs = await loadMaxRecordingMs();
console.log('[Audio] startRecording: autoStop=true, VAD-Stille=%dms, MAX=%dms',
vadSilenceMs, MAX_RECORDING_MS);
vadSilenceMs, maxRecordingMs);
this.vadTimer = setInterval(() => {
const silenceDuration = Date.now() - this.lastSpeechTime;
if (silenceDuration >= vadSilenceMs) {
fireSilenceOnce(`VAD ${silenceDuration}ms Stille (Schwelle=${vadSilenceMs}ms)`);
}
}, 200);
// Notbremse: Nach MAX_RECORDING_MS zwangsweise stoppen
// Notbremse: Nach maxRecordingMs zwangsweise stoppen
this.maxDurationTimer = setTimeout(() => {
fireSilenceOnce(`Max-Dauer ${MAX_RECORDING_MS}ms`);
}, MAX_RECORDING_MS);
fireSilenceOnce(`Max-Dauer ${maxRecordingMs}ms`);
}, maxRecordingMs);
}
// Conversation-Window: Wenn der User innerhalb noSpeechTimeoutMs nicht