I have a function tool and if I do context.wait_fo...
# ask-ai
m
I have a function tool and if I do context.wait_for_playout() in it then what will happen
Copy code
@function_tool
    @log_exceptions(logger=logger)
    async def provide_club_information(
        self,
        rephrased_user_query: str,
        context: RunContext,
    ):
        """Retrieve club-related information or policies based on the user's intent.
        """
        logger.debug(
            f"User Query Rephrased by provide_club_information tool: {rephrased_user_query}"
        )
        await context.wait_for_playout()
because I am getting error like this RuntimeError: cannot call
SpeechHandle.wait_for_playout()
from inside the function tool
provide_club_information
that owns this SpeechHandle. This creates a circular wait: the speech handle is waiting for the function tool to complete, while the function tool is simultaneously waiting for the speech handle.
t
Thanks for reaching out, Shataxi. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I see you're calling
await context.wait_for_playout()
from inside your
provide_club_information
function tool and getting this runtime error about a circular wait. You're right to question it — here's what is happening and how to fix it. What causes the RuntimeError •
context.wait_for_playout()
pauses until the agent's current speech finishes playing to the user. • The function tool
provide_club_information
is part of the agent's response generation. The agent waits for the tool to finish before it considers the response (and its speech) complete. • Calling
wait_for_playout()
from within the same tool makes the tool wait for the speech to finish, while the speech system is waiting for the tool to finish — a circular dependency that raises the RuntimeError. What you can do instead • Do not call
context.wait_for_playout()
from inside the tool that participates in generating the speech. That creates the circular wait. • Move the
wait_for_playout()
call outside the function tool, into the higher-level flow that invoked the tool (the agent/runner) so speech can complete first and then you can await playout. • If you need to coordinate actions relative to speech completion, use a callback or an external task that runs after the agent's response finishes, rather than blocking inside the tool. • If you only need to ensure audio is fully sent or finalized (not necessarily that speech finished playing to the user), consider other synchronization points your system exposes (for example, state/events provided by the agent runner) rather than
wait_for_playout()
inside the tool. If you'd like, tell me: • Where you currently call
provide_club_information
from (agent/runner code), and • What exact behavior you want after speech finishes (e.g., start another tool, log analytics, send follow-up message). With that I can suggest a concrete refactor or show an example pattern to await playout outside the tool. Sources: Agent speech and audio | LiveKit Documentation
m
But we do ctx.wait_for_playout() in end_call tool and it works perfectly there then what is the problem in my case
t
Thanks — that’s a good observation. The difference comes down to when the tool runs in the speech lifecycle and whether the tool itself is part of the response that is being played out. Why it works in your end_call tool • The
end_call
tool is typically invoked after the agent has finished generating the response and the speech playback has either finished or is in a state where waiting for playout does not depend on the tool completing. In other words,
end_call
runs outside (or after) the active speech’s critical path, so awaiting
ctx.wait_for_playout()
there does not create a circular dependency. Why it fails in provide_club_information •
provide_club_information
is being executed as part of the agent’s response generation. The agent will wait for that tool to return before it finalizes the response and completes the speech lifecycle. • Calling
await context.wait_for_playout()
inside that same tool makes the tool wait for speech to finish, while the speech system is waiting for the tool to finish. That is a circular wait — the speech handle cannot complete because the agent hasn't finished (the tool is still running), and the tool cannot finish because it’s waiting for speech to complete. That deadlock is what raises the RuntimeError. Key difference summary • end_call: runs after/outside the active speech path → waiting for playout is safe. • provide_club_information: runs inside the active speech path → waiting for playout causes circular wait and is disallowed. What to do instead • Move
await context.wait_for_playout()
out of
provide_club_information
into the caller/agent flow that invokes the tool, or into a tool that runs after the response/speech completes (like
end_call
). • If you need follow-up work when playback finishes, attach that work to a post-playout handler or schedule it as a separate async task that is triggered after the agent’s response completes. • If you share what behavior you want after playback (e.g., log analytics, start another tool, send a follow-up message), I can suggest a concrete pattern or code example that avoids the circular wait. If you want, paste the call site where
provide_club_information
is invoked or describe the exact sequence you expect after speech finishes, and I’ll propose a refactor you can use.