Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,22 @@
MAX_MESSAGES = 40
DEFAULT_MAX_SESSION_RESTART_ATTEMPTS = 3
DEFAULT_MAX_SESSION_RESTART_DELAY = 10
RECOVERABLE_VALIDATION_ERROR_MESSAGES = (
"InternalErrorCode=531::RST_STREAM closed stream. HTTP/2 error code: NO_ERROR",
"System instability detected. Please retry your request.",
)
# Session recycling: restart before 8-min AWS limit or credential expiry
# Override with LK_SESSION_MAX_DURATION env var for testing (e.g., "60" for 1 minute)
MAX_SESSION_DURATION_SECONDS = int(os.getenv("LK_SESSION_MAX_DURATION", 6 * 60))
CREDENTIAL_EXPIRY_BUFFER_SECONDS = 3 * 60 # Restart 3 min before credential expiry
BARGE_IN_SIGNAL = '{ "interrupted" : true }' # Nova Sonic's barge-in detection signal


def _is_recoverable_validation_error(exc: object) -> bool:
message = getattr(exc, "message", str(exc))
return any(text in message for text in RECOVERABLE_VALIDATION_ERROR_MESSAGES)


DEFAULT_SYSTEM_PROMPT = (
"Your name is Sonic, and you are a friendly and enthusiastic voice assistant. "
"You love helping people and having natural conversations. "
Expand Down Expand Up @@ -1500,11 +1511,10 @@ async def _process_responses(self) -> None:
self._close_current_generation()
raise
except ValidationException as ve:
# there is a 3min no-activity (e.g. silence) timeout on the stream, after which the stream is closed # noqa: E501
if (
"InternalErrorCode=531::RST_STREAM closed stream. HTTP/2 error code: NO_ERROR" # noqa: E501
in ve.message
):
# Some Bedrock ValidationException messages represent transient stream
# failures. Recover by restarting the Sonic session instead of tearing
# down the LiveKit session.
if _is_recoverable_validation_error(ve):
logger.warning(f"Validation error: {ve}\nAttempting to recover...")
await self._restart_session(ve)
elif "Tool Response parsing error" in ve.message:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from types import SimpleNamespace

from livekit.plugins.aws.experimental.realtime.realtime_model import (
_is_recoverable_validation_error,
)


def test_system_instability_validation_error_is_recoverable() -> None:
exc = SimpleNamespace(message="System instability detected. Please retry your request.")

assert _is_recoverable_validation_error(exc) is True


def test_unrecognized_validation_error_is_not_recoverable() -> None:
exc = SimpleNamespace(message="The provided request is invalid.")

assert _is_recoverable_validation_error(exc) is False
Loading