delightful-market-7668
03/31/2026, 11:18 AMresult = await session.start(agent, capture_run=True) gets stuck forever. Also, our agent starts the conversation, not the user, but session.run always expects a user_input, and the result contains no events, so we cannot capture the agent's tool calls or replies. What can we do?tall-airline-16756
03/31/2026, 11:19 AMtall-airline-16756
03/31/2026, 11:19 AMsession.start(..., capture_run=True) appears to hang, and (2) when your agent initiates the conversation, session.run() expects user input and you can’t capture the agent’s initial messages or tool calls. I’ll address both and give concrete steps you can try.
Why this happens (short)
• If an agent starts the conversation (for example it calls session.generate_reply() in on_enter()), calling session.run() is the wrong flow because session.run() is designed to accept a user input and won’t capture agent-initiated outputs.
• In Python, tests that use TaskGroup can briefly unset the LLM during task transitions. If you call session.run() too early (before the agent’s first sub-task/LLM is active), the runtime can error or appear to hang.
What to do — quick actionable fixes
1. Use capture_run=True with session.start() when the agent should speak first
◦ Start the session and capture the run so the session records any agent-initiated replies and tool calls:
result = await session.start(agent=agent, capture_run=True)
• The returned result contains events you can assert against (messages, function/tool calls, etc.).
1. If you still need to call session.run() after start(), add a small delay
◦ Give the task/LLM time to settle before calling `session.run(...)`:
await session.start()
await asyncio.sleep(0.5)
await session.run(user_input="...")
• This avoids the TaskGroup LLM transition problem that can cause the session to hang.
1. Validate agent replies and tool calls using the fluent assertion API
◦ Example checks you can run against the result from `capture_run=True`:
await result.expect.next_event().is_message(role="assistant").judge(llm, intent="Performs an initial greeting")
result.expect.contains_function_call(name="consent_given")
• These let you assert the agent’s initial message and any function/tool invocations.
If it’s still stuck or you see specific runtime errors
• Tell me the exact error message (if any) you see, and whether you’re using TaskGroup or other concurrency primitives.
• Share the minimal test flow: how you start the session, whether the agent calls generate_reply() in on_enter(), and where you call session.run().
I can then suggest the precise change or a small test snippet tailored to your setup.
Sources: Tasks and task groups | LiveKit Documentation | Testing and evaluation | LiveKit Documentation, with interactive elementsdelightful-market-7668
03/31/2026, 11:24 AMresult = await session.start(agent, capture_run=True)
print(f"Result: {result.events}")
produces no output, it just gets stuck there forever.
our agent does not use taskgroups or even an on_enter, we simply call session.generate_reply after starting the session:
result = await session.start(agent, capture_run=True)
print(f"Result: {result.events}") # never executes
await session.generate_reply()tall-airline-16756
03/31/2026, 11:24 AMcapture_run=True tells session.start() to wait for the agent to produce output during the start call. In your flow the agent does not produce output until you explicitly call session.generate_reply() after start(), so start(..., capture_run=True) waits forever for that (and never returns).
What you can do (pick one)
• Let start() return, then call generate_reply() and capture events
a. Start without capture:
await session.start(agent) # returns immediately
await session.generate_reply() # agent produces output
print(session.events) # now contains events
1. If you want the result object from a captured run, call start() then start(..., capture_run=True) is not appropriate here — use the pattern above and inspect session.events after generate_reply().
• Make the agent produce output during start (so capture_run works)
◦ Move the initial generate_reply() into the agent lifecycle that runs during start (for example on_enter() or similar). Then:
result = await session.start(agent, capture_run=True)
# result.events will contain the agent-initiated messages and tool calls
• Start with capture_run but trigger the reply immediately after start in the same async flow (not recommended unless agent emits immediately)
◦ If you truly need capture_run=True, the agent must produce output before start() finishes. For your current code, that means calling generate_reply() inside lifecycle code that runs as part of start().
Extra tips
• Don’t call capture_run=True if the agent only calls generate_reply() after start() returns — that causes the indefinite wait you’re seeing.
• If you want to assert agent messages/tool calls in tests, two common patterns:
◦ Pattern A (agent starts): agent emits on start -> use result = await session.start(agent, capture_run=True) and assert on result.
◦ Pattern B (test drives agent): start without capture -> call await session.generate_reply() from the test -> assert on session.events.
If you’d like, paste the small snippet showing how you create the agent and how/where you call generate_reply() and I’ll suggest the minimal change (move to on_enter vs change start/run usage) to get result.events populated.
, with interactive elementsdelightful-market-7668
03/31/2026, 11:28 AM