Skip to content

user_away_timeout getting triggered for SIP participant on telephony calls even when user is not speaking and taking background noise and conversations as user state speaking. #6030

Description

@abhishekdeepmindz

Bug Description

So, in my telephony voice AI agent application i have implemented a logic where after the user is away for configured time it will prompt the user whether they are still there with messages like are you still there? initially i had implemented it via llm, stt nodes by resetting a timer everytime a new speech or response was detected, purely on transripts, if no new transcripts then it would prompt the message. We moved to user_away_timeout session variables for easier calculation. But now this is causing the prompt message to not be called because we keep getting the state changes every second if there is background noise or background inaudible speech.
How does this work internally?
Following is my session parameters.

{ "allow_interruptions": true, "discard_audio_if_uninterruptible": true, "min_interruption_duration": 0.3, "min_interruption_words": 0, "min_endpointing_delay": 0.4, "max_endpointing_delay": 2, "max_tool_steps": 3, "user_away_timeout": 10, "min_consecutive_speech_delay": 0, "preemptive_generation": { "enabled": true, "preemptive_tts": true, "max_speech_duration": 10, "max_retries": 3 } }

Self hosted Livekit Instance, livekit agents version ~=1.5, using BVC Telephony

[EVENT] type='user_state_changed' old_state='speaking' new_state='listening' created_at=1780986023.7001052
[EVENT] type='user_state_changed' old_state='listening' new_state='speaking' created_at=1780985971.4367104
[EVENT] type='user_state_changed' old_state='listening' new_state='speaking' created_at=1780985971.4367104
[EVENT] type='user_state_changed' old_state='speaking' new_state='listening' created_at=1780986026.7517605
[EVENT] type='user_state_changed' old_state='listening' new_state='away' created_at=1780986036.752435

Expected Behavior

Should it be activated on background noise as well?

Reproduction Steps

@session.on("user_state_changed")
        def on_user_state_changed(ev):
            logger.info(f"[EVENT] {ev}")

            if ev.new_state == "away":
                logger.info("User is inactive")
                self.user_is_away = True

                # prevent duplicate loops
                if self.retry_task is None or self.retry_task.done():
                    self.retry_task = asyncio.create_task(self.handle_user_away(session))

            elif ev.new_state in ["speaking", "listening"]:
                logger.info("User is back")
                self.user_is_away = False
                self.idle_warning_count  = 0

                # cancel retry loop immediately
                if self.retry_task:
                    self.retry_task.cancel()
                    self.retry_task = None

Operating System

Linux VM

Models Used

Deepgram nova-3, gpt-oss 120B

Package Versions

livekit>=1.1.5
livekit-agents[azure,cartesia,deepgram,elevenlabs,google,groq,openai,sarvam]~=1.5

Session/Room/Call IDs

No response

Proposed Solution

Additional Context

No response

Screenshots and Recordings

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions