# Source: https://docs.pipecat.ai/server/utilities/user-idle-processor.md

> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pipecat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# UserIdleProcessor

> A processor that monitors user inactivity and triggers callbacks after specified timeout periods

<Warning>
  DEPRECATED: UserIdleProcessor has been deprecated. Use `user_idle_timeout`
  parameter when creating your aggregator, see [Detecting Idle
  Users](/guides/fundamentals/detecting-user-idle) for details.
</Warning>

The `UserIdleProcessor` is a specialized frame processor that monitors user activity in a conversation and executes callbacks when the user becomes idle. It's particularly useful for maintaining engagement by detecting periods of user inactivity and providing escalating responses to inactivity.

## Constructor Parameters

<ParamField path="callback" type="Union[BasicCallback, RetryCallback]" required>
  An async function that will be called when user inactivity is detected. Can be
  either:

  * Basic callback: `async def(processor: UserIdleProcessor) -> None`

  * Retry callback: `async def(processor: UserIdleProcessor, retry_count: int) ->
    bool` where returning `False` stops idle monitoring
</ParamField>

<ParamField path="timeout" type="float" required>
  The number of seconds to wait before considering the user idle.
</ParamField>

## Behavior

The processor starts monitoring for inactivity only after the first conversation activity (either `UserStartedSpeakingFrame` or `BotSpeakingFrame`). It manages idle state based on the following rules:

* Resets idle timer when user starts or stops speaking
* Pauses idle monitoring while user is speaking
* Resets idle timer when bot is speaking
* Stops monitoring on conversation end or cancellation
* Manages a retry count for the retry callback
* Stops monitoring when retry callback returns `False`

## Properties

<ParamField path="retry_count" type="int">
  The current number of retry attempts made to engage the user.
</ParamField>

## Example Implementations

Here are two example showing how to use the `UserIdleProcessor`: one with the basic callback and one with the retry callback:

<Tabs>
  <Tab title="Basic Callback">
    ```python  theme={null}
    from pipecat.frames.frames import LLMMessagesAppendFrame
    from pipecat.pipeline.pipeline import Pipeline
    from pipecat.processors.user_idle_processor import UserIdleProcessor

    async def handle_idle(user_idle: UserIdleProcessor) -> None:
        await user_idle.push_frame(
            LLMMessagesAppendFrame(
                [
                    {
                        "role": "system",
                        "content": "Ask the user if they are still there and try to prompt for some input.",
                    }
                ],
                run_llm=True,
            )
        )


    # Create the processor
    user_idle = UserIdleProcessor(callback=handle_idle, timeout=5.0)

    # Add to pipeline
    pipeline = Pipeline(
        [
            transport.input(),
            user_idle,  # Add the processor to monitor user activity
            context_aggregator.user(),
            # ... rest of pipeline
        ]
    )
    ```
  </Tab>

  <Tab title="Retry Callback">
    ```python  theme={null}
    from pipecat.frames.frames import EndFrame, LLMMessagesAppendFrame, TTSSpeakFrame
    from pipecat.pipeline.pipeline import Pipeline
    from pipecat.processors.user_idle_processor import UserIdleProcessor

    async def handle_user_idle(user_idle: UserIdleProcessor, retry_count: int) -> bool:
        if retry_count == 1:
            # First attempt: Gentle reminder
            await user_idle.push_frame(
                LLMMessagesAppendFrame(
                    [
                        {
                            "role": "system",
                            "content": "The user has been quiet. Politely and briefly ask if they're still there.",
                        }
                    ],
                    run_llm=True,
                )
            )
            return True
        elif retry_count == 2:
            # Second attempt: Direct prompt
            await user_idle.push_frame(
                LLMMessagesAppendFrame(
                    [
                        {
                            "role": "system",
                            "content": "The user is still inactive. Ask if they'd like to continue our conversation.",
                        }
                    ],
                    run_llm=True,
                )
            )
            return True
        else:
            # Third attempt: End conversation
            await user_idle.push_frame(
                TTSSpeakFrame("It seems like you're busy right now. Have a nice day!")
            )
            await task.queue_frame(EndFrame())
            return False  # Stop monitoring


    # Create the processor
    user_idle = UserIdleProcessor(callback=handle_user_idle, timeout=5.0)

    # Add to pipeline
    pipeline = Pipeline(
        [
            transport.input(),
            user_idle,  # Add the processor to monitor user activity
            context_aggregator.user(),
            # ... rest of pipeline
        ]
    )
    ```
  </Tab>
</Tabs>

## Frame Handling

The processor handles the following frame types:

* `UserStartedSpeakingFrame`: Marks user as active, resets idle timer and retry count
* `UserStoppedSpeakingFrame`: Starts idle monitoring
* `BotSpeakingFrame`: Resets idle timer
* `EndFrame` / `CancelFrame`: Stops idle monitoring

## Notes

* The idle callback won't be triggered while the user or bot is actively speaking
* The processor automatically cleans up its resources when the pipeline ends
* Basic callbacks are supported for backward compatibility