AgenSession Say method don't refresh AgentState

Hi everyone,

Just as I posted in my previous post, i’ve implemented a custom behaviour in my Python Livekit server to handle the request from my Reactjs client. When I’ve tried to implemented a custom component render by comproving the Agent State I noticed that It doesn’t gets update when it’s in the IDLE mode (I’m using a web speech recognizer an then submiting these text to my pyhon server) or even when I’m recieving the video and audio stream by using AgentSession Say (I’m also using the LiveAvatar plugin). Does anyone noticed something similar? Could it because my own implementation of the Agent in my server or it is also related why it never handle correctly the done callback?

Thank in advace for your work and time.

Based on the state model and events, a few key points explain what you’re seeing.

First, idle is a valid frontend state meaning “connected but waiting for input” and it’s considered isPending (connecting, initializing, idle) rather than active (listening/thinking/speaking) as defined in the Agent state guide. If your UI logic only reacts to canListen or active states, it won’t re-render on transitions into idle unless you explicitly handle agent.state.

Second, the frontend state updates only when the backend emits agent_state_changed, which updates the lk.agent.state participant attribute as described in Events and error handling. If you’re bypassing normal input flow (e.g., using Web Speech in the browser and manually submitting text without enabling RoomOptions.text_input), the session may never transition through listening → thinking → speaking, so state won’t change.

Third, session.say() and LiveAvatar do emit speech_created and should transition to speaking per the Agent session lifecycle. If that’s not happening, your custom Agent logic may be short‑circuiting the pipeline or not awaiting session methods correctly.

To narrow it down:

  • Are you using RoomOptions.text_input=True?

  • Are you observing agent_state_changed on the server?

  • Are you relying on raw agent.state instead of getters like canListen?

Hi, thank for your answer.

In the RoomOptions i’ve implemented my custom callback event this way:

room_options=room_io.RoomOptions(

        text_input=room_io.TextInputOptions(text_input_cb=custom_text_input_handler_tts)

    )

About the agent state, I’ve noticed that it keeps in listening mode (from my server and my frontend as you mentioned), and I’m also relying in raw state because I need the exact state to implement differents animations. The way I’m using right now is by updating the raw state using update_agent_state from the server so the front recieve the update correctly.